diff --git a/.ci/AppImageBuilder.yml b/.ci/AppImageBuilder.yml index 86184518c..22db9f151 100644 --- a/.ci/AppImageBuilder.yml +++ b/.ci/AppImageBuilder.yml @@ -51,6 +51,7 @@ 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 diff --git a/.ci/build.sh b/.ci/build.sh index 0aa6a499d..1b1e5825e 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -540,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 - # Deactivate the stuck dependency and try again. - sudo "$macports/bin/port" -f deactivate $stuck_dep + 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 + + # Stop if no errors were found. + break done # Remove MacPorts error detection log. @@ -566,6 +579,7 @@ else arm32) arch_deb="armhf";; *) arch_deb="$arch";; esac + grep -q " bullseye " /etc/apt/sources.list || echo [!] WARNING: System not running the expected Debian version # Establish general dependencies. pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream" diff --git a/.ci/dependencies_msys.txt b/.ci/dependencies_msys.txt index 1b9ccdcc8..22601b643 100644 --- a/.ci/dependencies_msys.txt +++ b/.ci/dependencies_msys.txt @@ -9,5 +9,6 @@ zlib libpng rtmidi libslirp +fluidsynth qt5-static qt5-translations diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..32eb262c9 --- /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 2326a920c..000000000 --- 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 000000000..cdbc0a56f --- /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 cc1ec7f8e..c03c50764 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 4fe86d5ec..000000000 --- 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 7b8b6eeb4..b76c2c260 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,7 @@ on: jobs: msys2: - name: "Windows MSYS2 Makefile (Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})" + name: "Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" runs-on: windows-2022 @@ -95,7 +95,7 @@ jobs: libvncserver: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 5f703a65f..000000000 --- a/.github/workflows/cmake.yml +++ /dev/null @@ -1,463 +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 - libslirp:p - fluidsynth: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 - libslirp-dev - libfluidsynth-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 - fluidsynth - 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 000000000..c09789bfc --- /dev/null +++ b/.github/workflows/cmake_linux.yml @@ -0,0 +1,122 @@ +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 + libvncserver-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 000000000..7a6edcde9 --- /dev/null +++ b/.github/workflows/cmake_macos.yml @@ -0,0 +1,127 @@ +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 + libvncserver + ${{ 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 000000000..a49f9488a --- /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 000000000..48503cc27 --- /dev/null +++ b/.github/workflows/cmake_windows_msys2.yml @@ -0,0 +1,149 @@ +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: Win32 GUI + qt: off + static: on + - 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 + libvncserver: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 fcfb16341..000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,303 +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 - libslirp:p - fluidsynth: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 - libslirp-dev - libfluidsynth-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 - fluidsynth - 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 000000000..a97951abf --- /dev/null +++ b/.github/workflows/codeql_linux.yml @@ -0,0 +1,112 @@ +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 + libvncserver-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 000000000..724bdc6f6 --- /dev/null +++ b/.github/workflows/codeql_macos.yml @@ -0,0 +1,108 @@ +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 + libvncserver + ${{ 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 000000000..5b0c2485f --- /dev/null +++ b/.github/workflows/codeql_windows_msys2.yml @@ -0,0 +1,141 @@ +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 + libvncserver: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 8af57ca9a..a6b50baf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 4.0 + VERSION 4.1 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) @@ -153,7 +153,6 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) cmake_dependent_option(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(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) @@ -197,7 +196,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/README.md b/README.md index a1e1b4432..370bc940e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ ===== [![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. @@ -30,8 +31,6 @@ Performance may vary depending on both host and guest configuration. Most emulat 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) @@ -67,7 +66,7 @@ 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 828fb1a21..070e5e52a 100644 --- a/cmake/flags-gcc-armv7.cmake +++ b/cmake/flags-gcc-armv7.cmake @@ -14,7 +14,7 @@ # Copyright 2021 David Hrdlička. # -string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard") -string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard") +string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard") +string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard") include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) diff --git a/debian/changelog b/debian/changelog index 1bca318dd..29ec6d3af 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (4.0) UNRELEASED; urgency=medium +86box (4.1) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Tue, 28 Feb 2023 00:02:16 -0500 + -- Jasmine Iwanek Mon, 16 Oct 2023 20:24:46 +0200 diff --git a/debian/control b/debian/control index 78a92bf8f..d67f5965b 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 22817edc5..58c9077fa 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 7b0605e72..1ee4be4ed 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) + 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 163aaf8d8..89ae9db8f 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 000000000..48817b27c --- /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 3a1ad179b..f72b066a5 100644 --- a/src/86box.c +++ b/src/86box.c @@ -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; @@ -225,6 +238,9 @@ int efscrnsz_y = SCREEN_RES_Y; 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; @@ -398,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. * @@ -416,6 +457,7 @@ pc_init(int argc, char *argv[]) char *fn[FDD_NUM] = { NULL }; char drive = 0; char *temp2 = NULL; + char *what; const struct tm *info; time_t now; int c; @@ -479,34 +521,40 @@ usage: 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; @@ -565,10 +613,38 @@ usage: 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")) { @@ -578,9 +654,8 @@ usage: 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]); @@ -590,13 +665,13 @@ usage: // 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; @@ -779,6 +854,18 @@ usage: /* Load the configuration file. */ config_load(); + /* 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) @@ -804,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 @@ -826,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; @@ -918,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 @@ -941,6 +1034,11 @@ pc_init_modules(void) machine_status_init(); + if (do_nothing) { + do_nothing = 0; + exit(-1); + } + return 1; } @@ -1048,19 +1146,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 @@ -1071,10 +1159,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. @@ -1084,25 +1181,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(); @@ -1118,6 +1223,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(); @@ -1196,10 +1312,6 @@ pc_close(UNUSED(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(); @@ -1256,6 +1368,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) { @@ -1271,12 +1392,15 @@ 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 0 - mouse_process(); + if (!mouse_timed) + mouse_process(); +#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ + } #endif joystick_process(); endblit(); @@ -1289,7 +1413,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. */ @@ -1463,3 +1587,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 3809ead73..ec32d7548 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 81ba781ab..9521d5337 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -46,6 +46,8 @@ int acpi_enabled = 0; static double cpu_to_acpi; +static int acpi_power_on = 0; + #ifdef ENABLE_ACPI_LOG int acpi_do_log = ENABLE_ACPI_LOG; @@ -122,20 +124,20 @@ acpi_update_irq(acpi_t *dev) if (dev->vendor == VEN_SMC) sci_level |= (dev->regs.pmsts & BM_STS); - if (sci_level) { + if ((dev->regs.pmcntrl & 0x01) && sci_level) { if (dev->irq_mode == 1) - pci_set_irq(dev->slot, dev->irq_pin); + pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); else if (dev->irq_mode == 2) - pci_set_mirq(5, dev->mirq_is_level); + pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state); else - pci_set_mirq(0xf0 | dev->irq_line, 1); + picintlevel(1 << dev->irq_line, &dev->irq_state); } else { if (dev->irq_mode == 1) - pci_clear_irq(dev->slot, dev->irq_pin); + pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); else if (dev->irq_mode == 2) - pci_clear_mirq(5, dev->mirq_is_level); + pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state); else - pci_clear_mirq(0xf0 | dev->irq_line, 1); + picintclevel(1 << dev->irq_line, &dev->irq_state); } acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS)); @@ -656,6 +658,7 @@ acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *p acpi_t *dev = (acpi_t *) priv; int shift16; int sus_typ; + uint8_t old; addr &= 0x3f; #ifdef ENABLE_ACPI_LOG @@ -682,6 +685,7 @@ acpi_reg_write_common_regs(UNUSED(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); @@ -719,11 +723,14 @@ acpi_reg_write_common_regs(UNUSED(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: @@ -787,7 +794,7 @@ acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *priv) 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: @@ -1619,7 +1626,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) @@ -1653,10 +1663,16 @@ 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; + } acpi_rtc_status = 0; + + acpi_update_irq(dev); + dev->irq_state = 0; } static void @@ -1723,6 +1739,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: @@ -1758,7 +1775,9 @@ acpi_init(const device_t *info) acpi_reset(dev); - acpi_enabled = 1; + acpi_enabled = 1; + acpi_power_on = 1; + return dev; } diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 3ca7e6885..c5755709d 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); @@ -531,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) { @@ -545,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; @@ -571,7 +569,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; } @@ -617,13 +614,73 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) 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). */ + /* 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_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; + + /* 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->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) { @@ -662,8 +719,13 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type) 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). */ + /* 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 = CD_STATUS_PLAYING; @@ -751,7 +813,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); @@ -766,7 +828,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; @@ -785,7 +847,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; @@ -820,36 +882,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) @@ -887,17 +974,35 @@ cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf) return ret; } -uint8_t -cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) +void +cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b) { - 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); + 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); +} - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->cd_status == CD_STATUS_PLAYING_COMPLETED)) +uint8_t +cdrom_get_current_subcodeq_playstatus(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) || + (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; @@ -957,9 +1062,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; } @@ -976,7 +1079,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; @@ -1029,7 +1132,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; @@ -1128,9 +1231,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; } @@ -1138,8 +1239,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; @@ -1154,7 +1255,6 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf b[len++] = temp; } } - return len; } @@ -1294,6 +1394,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); @@ -1333,11 +1434,32 @@ 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; @@ -1868,10 +1990,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. */ diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index d40c25d27..151ddfe9f 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 { @@ -203,7 +203,7 @@ static void cdi_clear_tracks(cd_img_t *cdi) { const track_file_t *last = NULL; - track_t *cur = NULL; + track_t *cur = NULL; if ((cdi->tracks == NULL) || (cdi->tracks_num == 0)) return; @@ -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; } @@ -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 @@ -652,9 +658,7 @@ cdi_cue_get_buffer(char *str, char **line, int up) done = 1; break; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; default: if (up && islower((int) *s)) diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 45182481d..7ed68cd86 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -121,8 +121,10 @@ typedef struct { 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 */ @@ -148,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; } @@ -247,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 '=': \ @@ -331,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; @@ -429,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. */ @@ -636,12 +649,8 @@ pad_susp: 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]; @@ -654,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. */ @@ -723,18 +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; + 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) @@ -743,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 @@ -794,8 +803,8 @@ 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. */ @@ -993,7 +1002,7 @@ next_dir: /* 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. */ @@ -1003,7 +1012,7 @@ next_dir: 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; @@ -1016,7 +1025,7 @@ next_dir: /* 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; @@ -1039,7 +1048,7 @@ next_dir: 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) { @@ -1056,10 +1065,10 @@ next_dir: 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; @@ -1111,7 +1120,7 @@ next_dir: 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. */ @@ -1120,7 +1129,7 @@ next_dir: 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; @@ -1131,20 +1140,20 @@ next_dir: 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; @@ -1154,22 +1163,22 @@ next_dir: 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; @@ -1199,21 +1208,21 @@ next_dir: *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. */ @@ -1226,12 +1235,12 @@ next_dir: 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; @@ -1248,7 +1257,7 @@ next_dir: /* 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; @@ -1284,7 +1293,7 @@ next_dir: *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) @@ -1295,17 +1304,17 @@ next_dir: } /* 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); } } @@ -1324,25 +1333,25 @@ next_dir: } /* 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; @@ -1362,15 +1371,15 @@ next_dir: 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. */ @@ -1383,13 +1392,13 @@ next_dir: } 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; @@ -1398,13 +1407,13 @@ next_entry: } /* 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; @@ -1412,11 +1421,11 @@ next_entry: } /* 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); } } @@ -1454,13 +1463,13 @@ next_entry: 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. */ @@ -1494,12 +1503,12 @@ next_entry: *((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. */ @@ -1525,22 +1534,22 @@ next_entry: 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 11ff14be2..7f4d2645b 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; @@ -244,6 +249,8 @@ 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; } @@ -324,9 +331,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) break; case 5: dev->readmsf = 0; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 4: case 3: dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3); @@ -396,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); @@ -421,6 +426,8 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) case 1: mitsumi_cdrom_reset(dev); break; + case 2: + break; default: break; } @@ -434,10 +441,10 @@ mitsumi_cdrom_init(UNUSED(const device_t *info)) 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/CMakeLists.txt b/src/chipset/CMakeLists.txt index 0a6a5fbe5..0f3c78c84 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -13,13 +13,14 @@ # 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 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) if(OLIVETTI) target_sources(chipset PRIVATE olivetti_eva.c) diff --git a/src/chipset/ali1435.c b/src/chipset/ali1435.c index 72595cf84..9476d2b45 100644 --- a/src/chipset/ali1435.c +++ b/src/chipset/ali1435.c @@ -46,11 +46,12 @@ 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; @@ -190,24 +191,20 @@ ali1435_write(uint16_t addr, uint8_t val, void *priv) break; case 0x23: -#if 0 -#ifdef ENABLE_ALI1435_LOG - if (dev->index != 0x03) - ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val); -#endif -#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; /* ???? */ @@ -253,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); @@ -298,17 +293,10 @@ ali1435_init(UNUSED(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); -#if 0 - 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); -#endif - return dev; } diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 1b2087e4d..3550f1da6 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -41,7 +41,8 @@ #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 @@ -64,19 +65,14 @@ ali1489_log(const char *fmt, ...) typedef struct ali1489_t { uint8_t index; - uint8_t ide_index; - uint8_t ide_chip_id; uint8_t pci_slot; uint8_t regs[256]; uint8_t pci_conf[256]; - uint8_t ide_regs[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) { @@ -85,7 +81,8 @@ ali1489_shadow_recalc(ali1489_t *dev) 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)); @@ -96,7 +93,8 @@ ali1489_shadow_recalc(ali1489_t *dev) 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); @@ -142,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; @@ -203,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 @@ -385,7 +365,8 @@ 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: @@ -464,121 +445,6 @@ ali1489_pci_read(UNUSED(int func), int addr, void *priv) 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; - } - break; - - default: - break; - } -} - -static uint8_t -ali1489_ide_read(uint16_t addr, void *priv) -{ - const 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; - - default: - break; - } - - return ret; -} - static void ali1489_reset(void *priv) { @@ -612,19 +478,10 @@ ali1489_init(UNUSED(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 3812e4ca4..9eb75f7cd 100644 --- a/src/chipset/ali1531.c +++ b/src/chipset/ali1531.c @@ -35,6 +35,11 @@ #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; @@ -374,7 +379,7 @@ 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 55cf5d25d..d57ef51e7 100644 --- a/src/chipset/ali1541.c +++ b/src/chipset/ali1541.c @@ -35,6 +35,11 @@ #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; @@ -641,7 +646,7 @@ 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 cefaa4f0d..fe3a0fda3 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -47,6 +47,7 @@ #include <86box/chipset.h> typedef struct ali1543_t { + uint8_t mirq_states[8]; uint8_t pci_conf[256]; uint8_t pmu_conf[256]; uint8_t usb_conf[256]; @@ -69,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; @@ -197,8 +197,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0xdf; soft_reset_pci = !!(val & 0x80); - sff_set_irq_level(dev->ide_controller[0], 0, !(val & 0x10)); - sff_set_irq_level(dev->ide_controller[1], 0, !(val & 0x10)); + pci_set_mirq_level(PCI_MIRQ2, !(val & 0x10)); ali1543_log("INTAJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ2, ali1533_irq_routing[val & 0x0f]); @@ -418,8 +417,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */ dev->pci_conf[addr] = val & 0x1f; - sff_set_irq_level(dev->ide_controller[0], 1, !(val & 0x10)); - sff_set_irq_level(dev->ide_controller[1], 1, !(val & 0x10)); + pci_set_mirq_level(PCI_MIRQ3, !(val & 0x10)); ali1543_log("INTBJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]); pci_set_mirq_routing(PCI_MIRQ3, ali1533_irq_routing[val & 0x0f]); @@ -491,46 +489,39 @@ 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: @@ -543,34 +534,29 @@ ali5229_ide_irq_handler(ali1543_t *dev) if (dev->ide_conf[0x09] & (4 ^ bit)) { /* Secondary IDE is native. */ ali1543_log("Secondary IDE IRQ mode: Native, Native\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 4); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 4); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_ALI_ALADDIN); } else { /* Secondary IDE is legacy. */ switch (dev->pci_conf[0x58] & 0x03) { case 0x00: /* SIRQI, SIRQII */ ali1543_log("Secondary IDE IRQ mode: SIRQI, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 2); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_MIRQ_0); break; case 0x01: /* IRQ14, IRQ15 */ ali1543_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 0); + sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_LEGACY); break; case 0x02: /* IRQ14, SIRQII */ ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQII\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_LEGACY); break; case 0x03: /* IRQ14, SIRQI */ ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQI\n"); - sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0); - sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2); + sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY); break; default: @@ -636,7 +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); } @@ -650,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 @@ -722,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); } @@ -844,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; @@ -996,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; @@ -1068,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; @@ -1079,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); @@ -1216,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; @@ -1418,70 +1406,81 @@ 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) { + default: + ret = dev->pmu_conf[addr]; + break; + case 0x10 ... 0x13: + if (dev->pmu_conf[0x5b] & 0x02) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; + break; + case 0x14 ... 0x17: + if (dev->pmu_conf[0x5b] & 0x04) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; + break; case 0x42: - dev->pmu_conf[addr] &= 0xe0; + ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00); break; case 0x43: - dev->pmu_conf[addr] &= 0xef; - acpi_ali_soft_smi_status_write(dev->acpi, 0); + ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; break; + case 0x7f: + ret = 0x80; + break; + case 0xbc: + ret = inb(0x70); + 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; + 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 0x4e: - dev->pmu_conf[addr] &= 0xfa; - break; - case 0x4f: - dev->pmu_conf[addr] &= 0xfe; - 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 0x74: - dev->pmu_conf[addr] &= 0xcc; - break; + case 0x4e: + dev->pmu_conf[addr] &= 0xfa; + break; + case 0x4f: + dev->pmu_conf[addr] &= 0xfe; + break; - default: - break; + case 0x74: + dev->pmu_conf[addr] &= 0xcc; + break; + + default: + break; + } } } } + ali1543_log("M7101: [R] dev->pmu_conf[%02x] = %02x\n", addr, ret); + return ret; } -static void -ali5237_usb_update_interrupt(usb_t* usb, void *priv) -{ - const ali1543_t *dev = (ali1543_t *) priv; - - if (usb->irq_level) - pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10)); - else - pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10)); -} - static void ali1543_reset(void *priv) { @@ -1595,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); @@ -1632,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 4e19dc6cd..6194dce19 100644 --- a/src/chipset/ali1621.c +++ b/src/chipset/ali1621.c @@ -28,6 +28,7 @@ #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> @@ -35,6 +36,11 @@ #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]; @@ -108,9 +114,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev) switch (val & 0x30) { case 0x10: /* Open. */ access_normal = ACCESS_SMRAM_RX; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x30: /* Protect. */ access_smm |= ACCESS_SMRAM_R; break; @@ -123,9 +127,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev) switch (val & 0x30) { case 0x10: /* Open. */ access_normal |= ACCESS_SMRAM_W; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x30: /* Protect. */ access_smm |= ACCESS_SMRAM_W; break; @@ -670,7 +672,7 @@ 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 c4b8b818a..c7ada4bc6 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -33,6 +33,7 @@ #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; @@ -233,9 +234,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x12: val &= 0xf7; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x14: case 0x15: diff --git a/src/chipset/compaq_386.c b/src/chipset/compaq_386.c new file mode 100644 index 000000000..7d55bc5a5 --- /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/ims8848.c b/src/chipset/ims8848.c index f84eb5706..3e86a44e1 100644 --- a/src/chipset/ims8848.c +++ b/src/chipset/ims8848.c @@ -122,6 +122,9 @@ 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]; @@ -392,7 +395,7 @@ ims8848_init(UNUSED(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 f7ffef13d..34335d53c 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 @@ -52,6 +53,9 @@ typedef struct i420ex_t { uint8_t has_ide; uint8_t smram_locked; + uint8_t pci_slot; + uint8_t pad; + uint8_t regs[256]; uint16_t timer_base; @@ -167,7 +171,7 @@ i420ex_drb_recalc(i420ex_t *dev) { uint32_t boundary; - for (uint8_t i = 4; i >= 0; i--) + for (int8_t i = 4; i >= 0; i--) row_disable(i); for (uint8_t i = 0; i <= 4; i++) { @@ -519,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) @@ -534,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; diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index c68f6218c..1e4158b94 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -57,6 +57,9 @@ typedef struct i4x0_t { 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]; @@ -1241,12 +1244,12 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) 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; @@ -1518,7 +1521,7 @@ i4x0_read(int func, int addr, void *priv) /* 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); } return ret; @@ -1669,11 +1672,12 @@ i4x0_init(const device_t *info) regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ regs[0x57] = 0x31; regs[0x59] = 0x0f; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; - dev->max_drb = 7; - dev->drb_unit = 1; - dev->drb_default = 0x02; - dev->write_drbs = spd_write_drbs_with_ext; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + dev->max_drb = 7; + dev->drb_unit = 1; + dev->drb_default = 0x02; + dev->write_drbs = spd_write_drbs_with_ext; break; case INTEL_430FX: regs[0x02] = 0x2d; @@ -1702,11 +1706,12 @@ i4x0_init(const device_t *info) regs[0x57] |= 0x02; else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) regs[0x57] |= 0x03; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; - regs[0x72] = 0x02; - dev->max_drb = 7; - dev->drb_unit = 4; - dev->drb_default = 0x02; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_unit = 4; + dev->drb_default = 0x02; break; case INTEL_430VX: regs[0x02] = 0x30; @@ -1761,12 +1766,13 @@ i4x0_init(const device_t *info) regs[0x53] = 0x80; regs[0x57] = 0x01; regs[0x58] = 0x10; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; - regs[0x71] = 0x10; - regs[0x72] = 0x02; - dev->max_drb = 7; - dev->drb_unit = 8; - dev->drb_default = 0x02; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x71] = 0x10; + regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_unit = 8; + dev->drb_default = 0x02; break; case INTEL_440LX: regs[0x02] = 0x80; @@ -1781,7 +1787,8 @@ i4x0_init(const device_t *info) regs[0x51] |= 0x00; regs[0x53] = 0x83; regs[0x57] = 0x01; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; regs[0x6c] = regs[0x6d] = regs[0x6e] = regs[0x6f] = 0x55; regs[0x72] = 0x02; regs[0xa0] = 0x02; @@ -1803,7 +1810,8 @@ i4x0_init(const device_t *info) regs[0x51] = 0x80; regs[0x53] = 0x83; regs[0x57] = 0x01; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; regs[0x6c] = regs[0x6d] = regs[0x6e] = regs[0x6f] = 0x55; regs[0x72] = 0x02; regs[0xa0] = 0x02; @@ -1831,19 +1839,20 @@ i4x0_init(const device_t *info) regs[0x51] |= 0x00; regs[0x57] = 0x28; /* 4 DIMMs, SDRAM */ regs[0x58] = 0x03; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; - regs[0x72] = 0x02; - regs[0x73] = 0x38; - regs[0x7b] = 0x38; - regs[0x90] = 0x80; - regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; - regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; - regs[0xa4] = 0x03; - regs[0xa5] = 0x02; - regs[0xa7] = 0x1f; - dev->max_drb = 7; - dev->drb_unit = 8; - dev->drb_default = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x72] = 0x02; + regs[0x73] = 0x38; + regs[0x7b] = 0x38; + regs[0x90] = 0x80; + regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; + regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_unit = 8; + dev->drb_default = 0x01; break; case INTEL_440GX: regs[0x7a] = (info->local >> 8) & 0xff; @@ -1854,19 +1863,20 @@ i4x0_init(const device_t *info) regs[0x10] = 0x08; regs[0x34] = (regs[0x7a] & 0x02) ? 0x00 : 0xa0; regs[0x57] = 0x28; - regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; - regs[0x72] = 0x02; - regs[0x73] = 0x38; - regs[0x7b] = 0x38; - regs[0x90] = 0x80; - regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; - regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; - regs[0xa4] = 0x03; - regs[0xa5] = 0x02; - regs[0xa7] = 0x1f; - dev->max_drb = 7; - dev->drb_unit = 8; - dev->drb_default = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = + regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x72] = 0x02; + regs[0x73] = 0x38; + regs[0x7b] = 0x38; + regs[0x90] = 0x80; + regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; + regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_unit = 8; + dev->drb_default = 0x01; break; default: break; @@ -1910,12 +1920,12 @@ i4x0_init(const device_t *info) (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); } @@ -2106,7 +2116,7 @@ const device_t i440bx_device = { }; const device_t i440bx_no_agp_device = { - .name = "Intel 82443BX", + .name = "Intel 82443BX (No AGP)", .internal_name = "i440bx_no_agp", .flags = DEVICE_PCI, .local = 0x8200 | INTEL_440BX, diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index b81c3dde4..90b807a6d 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -62,11 +62,15 @@ i450kx_log(const char *fmt, ...) typedef struct i450kx_t { smram_t *smram[2]; + 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]; - uint8_t bus_index; + uint8_t mem_state[2][256]; } i450kx_t; static void @@ -801,8 +805,8 @@ 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 038f35f97..49d720d8b 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -66,10 +66,8 @@ typedef struct _piix_ { uint8_t max_func; uint8_t pci_slot; uint8_t no_mirq0; - uint8_t pad; uint8_t regs[4][256]; uint8_t readout_regs[256]; - uint8_t board_config[2]; uint16_t func0_id; uint16_t nvr_io_base; uint16_t acpi_io_base; @@ -84,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 @@ -109,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: @@ -147,12 +144,10 @@ smsc_ide_irqs(piix_t *dev) } sff_set_irq_line(dev->bm[0], irq_line); - sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[0], irq_mode[0]); sff_set_irq_line(dev->bm[1], irq_line); - sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]); - sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]); + sff_set_irq_mode(dev->bm[1], irq_mode[1]); } static void @@ -602,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; @@ -1011,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) { @@ -1177,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); } @@ -1191,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; @@ -1205,11 +1202,7 @@ board_read(uint16_t port, void *priv) 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]; @@ -1222,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 @@ -1443,17 +1432,6 @@ piix_fast_off_count(void *priv) dev->regs[0][0xaa] |= 0x20; } -static void -piix_usb_update_interrupt(usb_t* usb, void *priv) -{ - const 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 *priv) { @@ -1524,16 +1502,12 @@ piix_reset(void *priv) piix_write(3, 0xd2, 0x00, priv); } - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[1], 0, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - if (dev->no_mirq0 || (dev->type >= 4)) { - sff_set_irq_mode(dev->bm[0], 1, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); - } else { - sff_set_irq_mode(dev->bm[0], 1, 2); - sff_set_irq_mode(dev->bm[1], 1, 2); - } + if (dev->no_mirq0 || (dev->type >= 4)) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + else + sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0); } static void @@ -1554,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); } @@ -1574,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); @@ -1587,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); @@ -1638,7 +1604,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(); @@ -1679,37 +1648,8 @@ 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; - #if 0 device_add(&i8254_sec_device); #endif diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index 1dcbafe5a..03a292da8 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -37,6 +37,10 @@ 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; @@ -493,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) @@ -507,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; diff --git a/src/chipset/neat.c b/src/chipset/neat.c index a54fc312e..3b00b4ffd 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -673,13 +673,14 @@ neat_init(UNUSED(const device_t *info)) { neat_t *dev; uint8_t dram_mode = 0; + uint8_t i; /* Create an instance. */ dev = (neat_t *) malloc(sizeof(neat_t)); memset(dev, 0x00, sizeof(neat_t)); /* Initialize some of the registers to specific defaults. */ - for (uint8_t i = REG_RA0; i <= REG_RB11; i++) { + for (i = REG_RA0; i <= REG_RB11; i++) { dev->indx = i; neat_write(0x0023, 0x00, dev); } diff --git a/src/chipset/olivetti_eva.c b/src/chipset/olivetti_eva.c index 2f43a01f1..1f5eacc6c 100644 --- a/src/chipset/olivetti_eva.c +++ b/src/chipset/olivetti_eva.c @@ -102,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; diff --git a/src/chipset/opti283.c b/src/chipset/opti283.c index 544302b28..1fa59f2f0 100644 --- a/src/chipset/opti283.c +++ b/src/chipset/opti283.c @@ -29,6 +29,7 @@ #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> @@ -228,9 +229,7 @@ opti283_write(uint16_t addr, uint8_t val, void *priv) case 0x14: reset_on_hlt = !!(val & 0x40); -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x11: case 0x12: case 0x13: diff --git a/src/chipset/opti499.c b/src/chipset/opti499.c index acac4d87b..f8b878559 100644 --- a/src/chipset/opti499.c +++ b/src/chipset/opti499.c @@ -33,7 +33,7 @@ #include <86box/chipset.h> typedef struct opti499_t { - uint8_t idx, + uint8_t idx; uint8_t regs[256]; uint8_t scratch[2]; } opti499_t; diff --git a/src/chipset/opti602.c b/src/chipset/opti602.c new file mode 100644 index 000000000..3b5614ff4 --- /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 73548adab..3e9316f2b 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -43,6 +43,10 @@ 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; @@ -380,9 +384,9 @@ 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); } @@ -393,7 +397,7 @@ 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 8bc93702f..77297ae95 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -140,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; @@ -155,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); @@ -213,12 +216,14 @@ 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]; @@ -228,6 +233,8 @@ opti895_read(uint16_t addr, void *priv) break; } + opti895_log("opti895_read(%04X) = %02X\n", addr, ret); + return ret; } diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index dc2ef42e4..e58066c95 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -8,11 +8,11 @@ * * Implementation of the SiS 5511/5512/5513 Pentium PCI/ISA Chipset. * + * Authors: Miran Grca, + * Tiseno100, * - * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. + * Copyright 2021-2023 Miran Grca. + * Copyright 2021-2023 Tiseno100. */ #include #include @@ -27,26 +27,23 @@ #include <86box/timer.h> #include <86box/mem.h> +#include <86box/nvr.h> #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> #include <86box/pci.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/plat.h> #include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/smram.h> +#include <86box/spd.h> #include <86box/chipset.h> -/* IDE Flags (1 Native / 0 Compatibility)*/ -#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1) -#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4) -#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8) -#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2) -#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8) -#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2) -#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) - #ifdef ENABLE_SIS_5511_LOG int sis_5511_do_log = ENABLE_SIS_5511_LOG; @@ -66,18 +63,28 @@ sis_5511_log(const char *fmt, ...) #endif typedef struct sis_5511_t { + uint8_t index; + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t pad; + + uint8_t regs[16]; + uint8_t states[7]; + + uint8_t slic_regs[4096]; + uint8_t pci_conf[256]; uint8_t pci_conf_sb[2][256]; - uint8_t index; - uint8_t regs[16]; - int nb_pci_slot; - int sb_pci_slot; + mem_mapping_t slic_mapping; - sff8038i_t *ide_drive[2]; + sff8038i_t *bm[2]; smram_t *smram; port_92_t *port_92; + void *pit; + nvr_t *nvr; + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); } sis_5511_t; static void @@ -88,23 +95,31 @@ sis_5511_shadow_recalc(sis_5511_t *dev) for (uint8_t i = 0x80; i <= 0x86; i++) { if (i == 0x86) { - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(0xf0000, 0x10000, state); - pclog("000F0000-000FFFFF\n"); + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xf0000, 0x10000, state); + sis_5511_log("000F0000-000FFFFF\n"); + } } else { base = ((i & 0x07) << 15) + 0xc0000; - state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base, 0x4000, state); - pclog("%08X-%08X\n", base, base + 0x3fff); + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) { + state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base, 0x4000, state); + sis_5511_log("%08X-%08X\n", base, base + 0x3fff); + } - state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; - state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; - mem_set_mem_state_both(base + 0x4000, 0x4000, state); - pclog("%08X-%08X\n", base + 0x4000, base + 0x7fff); + if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) { + state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(base + 0x4000, 0x4000, state); + sis_5511_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } } + + dev->states[i & 0x0f] = dev->pci_conf[i]; } flushmmucache_nopc(); @@ -133,38 +148,14 @@ sis_5511_smram_recalc(sis_5511_t *dev) flushmmucache(); } -void -sis_5513_ide_handler(sis_5511_t *dev) -{ - ide_pri_disable(); - ide_sec_disable(); - if (dev->pci_conf_sb[1][4] & 1) { - if (dev->pci_conf_sb[1][0x4a] & 4) { - ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0); - ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6); - ide_pri_enable(); - } - if (dev->pci_conf_sb[1][0x4a] & 2) { - ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170); - ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376); - ide_sec_enable(); - } - } -} - -void -sis_5513_bm_handler(sis_5511_t *dev) -{ - sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE); - sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8); -} - static void sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv) { sis_5511_t *dev = (sis_5511_t *) priv; - switch (addr) { + sis_5511_log("SiS 5511: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + if (func == 0x00) switch (addr) { case 0x07: /* Status - High Byte */ dev->pci_conf[addr] &= 0xb0; break; @@ -264,106 +255,120 @@ sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x70: /* DRAM Bank Register 0-0 */ - case 0x71: /* DRAM Bank Register 0-0 */ case 0x72: /* DRAM Bank Register 0-1 */ - dev->pci_conf[addr] = val; - break; - - case 0x73: /* DRAM Bank Register 0-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - case 0x74: /* DRAM Bank Register 1-0 */ + case 0x76: /* DRAM Bank Register 1-1 */ + case 0x78: /* DRAM Bank Register 2-0 */ + case 0x7a: /* DRAM Bank Register 2-1 */ + case 0x7c: /* DRAM Bank Register 3-0 */ + case 0x7e: /* DRAM Bank Register 3-1 */ + spd_write_drbs(dev->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 */ - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x76: /* DRAM Bank Register 1-1 */ - dev->pci_conf[addr] = val; - break; - - case 0x77: /* DRAM Bank Register 1-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x78: /* DRAM Bank Register 2-0 */ - dev->pci_conf[addr] = val; - break; - case 0x79: /* DRAM Bank Register 2-0 */ - dev->pci_conf[addr] = val & 0x7f; - break; - - case 0x7a: /* DRAM Bank Register 2-1 */ - dev->pci_conf[addr] = val; - break; - - case 0x7b: /* DRAM Bank Register 2-1 */ - dev->pci_conf[addr] = val & 0x83; - break; - - case 0x7c: /* DRAM Bank Register 3-0 */ - dev->pci_conf[addr] = val; - break; - case 0x7d: /* DRAM Bank Register 3-0 */ dev->pci_conf[addr] = val & 0x7f; break; - case 0x7e: /* DRAM Bank Register 3-1 */ - dev->pci_conf[addr] = val; - break; - + case 0x73: /* DRAM Bank Register 0-1 */ + case 0x77: /* DRAM Bank Register 1-1 */ + case 0x7b: /* DRAM Bank Register 2-1 */ case 0x7f: /* DRAM Bank Register 3-1 */ dev->pci_conf[addr] = val & 0x83; break; - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: + case 0x80 ... 0x85: + dev->pci_conf[addr] = val & 0xee; + sis_5511_shadow_recalc(dev); + break; case 0x86: - dev->pci_conf[addr] = val & ((addr == 0x86) ? 0xe8 : 0xee); + dev->pci_conf[addr] = val & 0xe8; sis_5511_shadow_recalc(dev); break; - case 0x90: /* 5512 General Purpose Register Index */ - case 0x91: /* 5512 General Purpose Register Index */ - case 0x92: /* 5512 General Purpose Register Index */ - case 0x93: /* 5512 General Purpose Register Index */ + case 0x90 ... 0x93: /* 5512 General Purpose Register Index */ dev->pci_conf[addr] = val; break; default: break; } - sis_5511_log("SiS 5511: dev->pci_conf[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80)); +} + +static void +sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv) +{ + sis_5511_t *dev = (sis_5511_t *) priv; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000000: + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + dev->slic_regs[addr] = val; + break; + case 0x00000010: + case 0x00000018: + case 0x00000028: + case 0x00000038: + dev->slic_regs[addr] = val & 0x01; + break; + case 0x00000030: + dev->slic_regs[addr] = val & 0x0f; + mem_mapping_set_addr(&dev->slic_mapping, + (((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000); + break; + } } static uint8_t sis_5511_read(UNUSED(int func), int addr, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; - sis_5511_log("SiS 5511: dev->pci_conf[%02x] (%02x) POST %02x\n", addr, dev->pci_conf[addr], inb(0x80)); - return dev->pci_conf[addr]; + if (func == 0x00) + ret = dev->pci_conf[addr]; + + sis_5511_log("SiS 5511: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + + return ret; +} + +static uint8_t +sis_5511_slic_read(uint32_t addr, void *priv) +{ + sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; + + addr &= 0x00000fff; + + switch (addr) { + case 0x00000008: /* 0x00000008 is a SiS 5512 register. */ + ret = dev->slic_regs[addr]; + break; + } + + return ret; } void sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) { + sis_5511_log("SiS 5513 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val); + switch (addr) { case 0x04: /* Command */ - dev->pci_conf_sb[0][addr] = val & 7; + dev->pci_conf_sb[0][addr] = val & 0x0f; break; case 0x07: /* Status */ - dev->pci_conf_sb[0][addr] &= val & 0x36; + dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x06) & ~(val & 0x30); break; case 0x40: /* BIOS Control Register */ @@ -375,40 +380,24 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) case 0x43: /* INTC# Remapping Control Register */ case 0x44: /* INTD# Remapping Control Register */ dev->pci_conf_sb[0][addr] = val & 0x8f; - pci_set_irq_routing(addr & 7, (val & 0x80) ? (val & 0x80) : PCI_IRQ_DISABLED); + pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f)); break; case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */ case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */ case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */ case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */ - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: dev->pci_conf_sb[0][addr] = val; break; case 0x60: /* MIRQ0 Remapping Control Register */ case 0x61: /* MIRQ1 Remapping Control Register */ + sis_5511_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); dev->pci_conf_sb[0][addr] = val & 0xcf; - pci_set_mirq_routing(addr & 1, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); break; case 0x62: /* On-board Device DMA Control Register */ @@ -416,11 +405,12 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) break; case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5511_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); dev->pci_conf_sb[0][addr] = val & 0x8f; - if (val & 0x80) { - sff_set_irq_line(dev->ide_drive[0], (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - sff_set_irq_line(dev->ide_drive[1], (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); - } + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ2, val & 0xf); break; case 0x64: /* GPIO0 Control Register */ @@ -437,7 +427,8 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) break; case 0x6a: /* GPIO Status Register */ - dev->pci_conf_sb[0][addr] &= val & 0x15; + dev->pci_conf_sb[0][addr] |= (val & 0x10); + dev->pci_conf_sb[0][addr] &= ~(val & 0x01); break; default: @@ -445,52 +436,139 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev) } } +static void +sis_5513_ide_irq_handler(sis_5511_t *dev) +{ + if (dev->pci_conf_sb[1][0x09] & 0x01) { + /* Primary IDE is native. */ + sis_5511_log("Primary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X); + } else { + /* Primary IDE is legacy. */ + sis_5511_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); + } + + if (dev->pci_conf_sb[1][0x09] & 0x04) { + /* Secondary IDE is native. */ + sis_5511_log("Secondary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X); + } else { + /* Secondary IDE is legacy. */ + sis_5511_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + } +} + +static void +sis_5513_ide_handler(sis_5511_t *dev) +{ + uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01; + + uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe; + uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe; + uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe; + uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe; + + uint16_t current_pri_base; + uint16_t current_pri_side; + uint16_t current_sec_base; + uint16_t current_sec_side; + + /* Primary Channel Programming */ + current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr; + current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr; + + /* Secondary Channel Programming */ + current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr; + current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr; + + sis_5511_log("sis_5513_ide_handler(): Disabling primary IDE...\n"); + ide_pri_disable(); + sis_5511_log("sis_5513_ide_handler(): Disabling secondary IDE...\n"); + ide_sec_disable(); + + if (ide_io_on) { + /* Primary Channel Setup */ + if (dev->pci_conf_sb[1][0x4a] & 0x02) { + sis_5511_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); + ide_set_base(0, current_pri_base); + sis_5511_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); + ide_set_side(0, current_pri_side); + + sis_5511_log("sis_5513_ide_handler(): Enabling primary IDE...\n"); + ide_pri_enable(); + + sis_5511_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); + } + + /* Secondary Channel Setup */ + if (dev->pci_conf_sb[1][0x4a] & 0x04) { + sis_5511_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); + ide_set_base(1, current_sec_base); + sis_5511_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); + ide_set_side(1, current_sec_side); + + sis_5511_log("sis_5513_ide_handler(): Enabling secondary IDE...\n"); + ide_sec_enable(); + + sis_5511_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); + } + } + + sff_bus_master_handler(dev->bm[0], ide_io_on, + ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0); + sff_bus_master_handler(dev->bm[1], ide_io_on, + ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8); +} + void sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev) { + sis_5511_log("SiS 5513 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val); + switch (addr) { case 0x04: /* Command low byte */ - dev->pci_conf_sb[1][addr] = val & 5; + dev->pci_conf_sb[1][addr] = val & 0x05; sis_5513_ide_handler(dev); - sis_5513_bm_handler(dev); + break; + case 0x06: /* Status low byte */ + dev->pci_conf_sb[1][addr] = val & 0x20; break; case 0x07: /* Status high byte */ - dev->pci_conf_sb[1][addr] &= val & 0x3f; + dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38); break; case 0x09: /* Programming Interface Byte */ - dev->pci_conf_sb[1][addr] = val; + dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x05); + sis_5513_ide_irq_handler(dev); sis_5513_ide_handler(dev); break; case 0x0d: /* Latency Timer */ dev->pci_conf_sb[1][addr] = val; break; - case 0x10: /* Primary Channel Base Address Register */ - case 0x11: /* Primary Channel Base Address Register */ - case 0x12: /* Primary Channel Base Address Register */ - case 0x13: /* Primary Channel Base Address Register */ - case 0x14: /* Primary Channel Base Address Register */ - case 0x15: /* Primary Channel Base Address Register */ - case 0x16: /* Primary Channel Base Address Register */ - case 0x17: /* Primary Channel Base Address Register */ - case 0x18: /* Secondary Channel Base Address Register */ - case 0x19: /* Secondary Channel Base Address Register */ - case 0x1a: /* Secondary Channel Base Address Register */ - case 0x1b: /* Secondary Channel Base Address Register */ - case 0x1c: /* Secondary Channel Base Address Register */ - case 0x1d: /* Secondary Channel Base Address Register */ - case 0x1e: /* Secondary Channel Base Address Register */ - case 0x1f: /* Secondary Channel Base Address Register */ - dev->pci_conf_sb[1][addr] = val; - sis_5513_ide_handler(dev); - break; + /* Primary Base Address */ + case 0x10: + case 0x11: + case 0x14: + case 0x15: + fallthrough; - case 0x20: /* Bus Master IDE Control Register Base Address */ - case 0x21: /* Bus Master IDE Control Register Base Address */ - case 0x22: /* Bus Master IDE Control Register Base Address */ - case 0x23: /* Bus Master IDE Control Register Base Address */ - dev->pci_conf_sb[1][addr] = val; - sis_5513_bm_handler(dev); + /* Secondary Base Address */ + case 0x18: + case 0x19: + case 0x1c: + case 0x1d: + fallthrough; + + /* Bus Mastering Base Address */ + case 0x20: + case 0x21: + if (addr == 0x20) + dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01; + else + dev->pci_conf_sb[1][addr] = val; + sis_5513_ide_handler(dev); break; case 0x30: /* Expansion ROM Base Address */ @@ -501,20 +579,23 @@ sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev) 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 */ + dev->pci_conf_sb[1][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 */ case 0x49: /* IDE Command Active Time Control */ - dev->pci_conf_sb[1][addr] = val; + dev->pci_conf_sb[1][addr] = val & 0x07; break; case 0x4a: /* IDE General Control Register 0 */ - dev->pci_conf_sb[1][addr] = val & 0x9f; + dev->pci_conf_sb[1][addr] = val & 0x9e; sis_5513_ide_handler(dev); break; @@ -538,30 +619,59 @@ static void sis_5513_write(int func, int addr, uint8_t val, void *priv) { sis_5511_t *dev = (sis_5511_t *) priv; + switch (func) { + default: + break; case 0: sis_5513_pci_to_isa_write(addr, val, dev); break; case 1: sis_5513_ide_write(addr, val, dev); break; - - default: - break; } - sis_5511_log("SiS 5513: dev->pci_conf[%02x][%02x] = %02x POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); } static uint8_t sis_5513_read(int func, int addr, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; - sis_5511_log("SiS 5513: dev->pci_conf[%02x][%02x] = %02x POST %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80)); - if ((func >= 0) && (func <= 1)) - return dev->pci_conf_sb[func][addr]; - else - return 0xff; + if (func == 0x00) { + switch (addr) { + default: + ret = dev->pci_conf_sb[func][addr]; + break; + case 0x4c ... 0x4f: + ret = pic_read_icw(0, addr & 0x03); + break; + case 0x50 ... 0x53: + ret = pic_read_icw(1, addr & 0x03); + break; + case 0x54 ... 0x55: + ret = pic_read_ocw(0, addr & 0x01); + break; + case 0x56 ... 0x57: + ret = pic_read_ocw(1, addr & 0x01); + break; + case 0x58 ... 0x5f: + ret = dev->pit_read_reg(dev->pit, addr & 0x07); + break; + } + + sis_5511_log("SiS 5513 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret); + } else if (func == 0x01) { + if (addr == 0x3d) + ret = (((dev->pci_conf_sb[0x01][0x4b] & 0xc0) == 0xc0) || + (dev->pci_conf_sb[0x01][0x09] & 0x05)) ? PCI_INTA : 0x00; + else + ret = dev->pci_conf_sb[func][addr]; + + sis_5511_log("SiS 5513 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret); + } + + return ret; } static void @@ -574,6 +684,8 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) dev->index = val - 0x50; break; case 0x23: + sis_5511_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val); + switch (dev->index) { case 0x00: dev->regs[dev->index] = val & 0xed; @@ -591,6 +703,7 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) default: break; } + nvr_bank_set(0, !!(val & 0x08), dev->nvr); break; case 0x01: dev->regs[dev->index] = val & 0xf4; @@ -602,7 +715,8 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) dev->regs[dev->index] = val; break; case 0x05: - dev->regs[dev->index] = inb(0x70); + dev->regs[dev->index] = val; + outb(0x70, val); break; case 0x08: case 0x09: @@ -614,7 +728,6 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv) default: break; } - sis_5511_log("SiS 5513-ISA: dev->regs[%02x] = %02x POST: %02x\n", dev->index + 0x50, dev->regs[dev->index], inb(0x80)); break; default: @@ -626,12 +739,18 @@ static uint8_t sis_5513_isa_read(uint16_t addr, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; + uint8_t ret = 0xff; if (addr == 0x23) { - sis_5511_log("SiS 5513-ISA: dev->regs[%02x] (%02x) POST: %02x\n", dev->index + 0x50, dev->regs[dev->index], inb(0x80)); - return dev->regs[dev->index]; - } else - return 0xff; + if (dev->index == 0x05) + ret = inb(0x70); + else + ret = dev->regs[dev->index]; + + sis_5511_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret); + } + + return ret; } static void @@ -665,58 +784,127 @@ sis_5511_reset(void *priv) dev->pci_conf[0x66] = 0x00; dev->pci_conf[0x67] = 0xff; dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00; - dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00; - dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00; - dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x6a] = 0x00; + dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff; + dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff; + dev->pci_conf[0x6f] = 0x00; + dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04; + dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04; + dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04; + dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04; + dev->pci_conf[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(); - dev->pci_conf[0x6b] = 0xff; - dev->pci_conf[0x6c] = 0xff; - dev->pci_conf[0x70] = 4; - dev->pci_conf[0x72] = 4; - dev->pci_conf[0x73] = 0x80; - dev->pci_conf[0x74] = 4; - dev->pci_conf[0x76] = 4; - dev->pci_conf[0x77] = 0x80; - dev->pci_conf[0x78] = 4; - dev->pci_conf[0x7a] = 4; - dev->pci_conf[0x7b] = 0x80; - dev->pci_conf[0x7c] = 4; - dev->pci_conf[0x7e] = 4; - dev->pci_conf[0x7f] = 0x80; - dev->pci_conf[0x80] = 0x00; - dev->pci_conf[0x81] = 0x00; - dev->pci_conf[0x82] = 0x00; - dev->pci_conf[0x83] = 0x00; - dev->pci_conf[0x84] = 0x00; - dev->pci_conf[0x85] = 0x00; - dev->pci_conf[0x86] = 0x00; sis_5511_smram_recalc(dev); sis_5511_shadow_recalc(dev); + flushmmucache(); + + memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t)); + dev->slic_regs[0x18] = 0x0f; + + mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000); + /* SiS 5513 */ dev->pci_conf_sb[0][0x00] = 0x39; dev->pci_conf_sb[0][0x01] = 0x10; - dev->pci_conf_sb[0][0x02] = 8; - dev->pci_conf_sb[0][0x04] = 7; - dev->pci_conf_sb[0][0x0a] = 1; - dev->pci_conf_sb[0][0x0b] = 6; + dev->pci_conf_sb[0][0x02] = 0x08; + dev->pci_conf_sb[0][0x03] = 0x00; + dev->pci_conf_sb[0][0x04] = 0x07; + dev->pci_conf_sb[0][0x05] = dev->pci_conf_sb[0][0x06] = 0x00; + dev->pci_conf_sb[0][0x07] = 0x02; + dev->pci_conf_sb[0][0x08] = dev->pci_conf_sb[0][0x09] = 0x00; + dev->pci_conf_sb[0][0x0a] = 0x01; + dev->pci_conf_sb[0][0x0b] = 0x06; dev->pci_conf_sb[0][0x0e] = 0x80; + dev->pci_conf_sb[0][0x40] = 0x00; + dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80; + dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80; + dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x00; + dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x00; + dev->pci_conf_sb[0][0x60] = dev->pci_conf_sb[0][0x61] = 0x80; + dev->pci_conf_sb[0][0x62] = 0x00; + dev->pci_conf_sb[0][0x63] = 0x80; + dev->pci_conf_sb[0][0x64] = 0x00; + dev->pci_conf_sb[0][0x65] = 0x00; + dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00; + dev->pci_conf_sb[0][0x68] = dev->pci_conf_sb[0][0x69] = 0x00; + dev->pci_conf_sb[0][0x6a] = 0x04; + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + + pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + + dev->regs[0x00] = dev->regs[0x01] = 0x00; + dev->regs[0x03] = dev->regs[0x04] = 0x00; + dev->regs[0x05] = 0x00; + dev->regs[0x08] = dev->regs[0x09] = 0x00; + dev->regs[0x0a] = dev->regs[0x0b] = 0x00; + + cpu_set_isa_speed(7159091); + nvr_bank_set(0, 0, dev->nvr); /* SiS 5513 IDE Controller */ dev->pci_conf_sb[1][0x00] = 0x39; dev->pci_conf_sb[1][0x01] = 0x10; dev->pci_conf_sb[1][0x02] = 0x13; dev->pci_conf_sb[1][0x03] = 0x55; - dev->pci_conf_sb[1][0x0a] = 1; - dev->pci_conf_sb[1][0x0b] = 1; + dev->pci_conf_sb[1][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; + dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00; + dev->pci_conf_sb[1][0x08] = 0x00; + dev->pci_conf_sb[1][0x09] = 0x8a; + dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; dev->pci_conf_sb[1][0x0e] = 0x80; - sff_set_slot(dev->ide_drive[0], dev->sb_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); + dev->pci_conf_sb[1][0x0f] = 0x00; + dev->pci_conf_sb[1][0x10] = 0xf1; + dev->pci_conf_sb[1][0x11] = 0x01; + dev->pci_conf_sb[1][0x14] = 0xf5; + dev->pci_conf_sb[1][0x15] = 0x03; + dev->pci_conf_sb[1][0x18] = 0x71; + dev->pci_conf_sb[1][0x19] = 0x01; + dev->pci_conf_sb[1][0x1c] = 0x75; + dev->pci_conf_sb[1][0x1d] = 0x03; + dev->pci_conf_sb[1][0x20] = 0x01; + dev->pci_conf_sb[1][0x21] = 0xf0; + dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00; + dev->pci_conf_sb[1][0x24] = dev->pci_conf_sb[1][0x25] = 0x00; + dev->pci_conf_sb[1][0x26] = dev->pci_conf_sb[1][0x27] = 0x00; + dev->pci_conf_sb[1][0x28] = dev->pci_conf_sb[1][0x29] = 0x00; + dev->pci_conf_sb[1][0x2a] = dev->pci_conf_sb[1][0x2b] = 0x00; + dev->pci_conf_sb[1][0x2c] = dev->pci_conf_sb[1][0x2d] = 0x00; + dev->pci_conf_sb[1][0x2e] = dev->pci_conf_sb[1][0x2f] = 0x00; + dev->pci_conf_sb[1][0x30] = dev->pci_conf_sb[1][0x31] = 0x00; + dev->pci_conf_sb[1][0x32] = dev->pci_conf_sb[1][0x33] = 0x00; + dev->pci_conf_sb[1][0x40] = 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] = 0x06; + dev->pci_conf_sb[1][0x4b] = 0x00; + dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x00; + dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0x00; + + sis_5513_ide_irq_handler(dev); + sis_5513_ide_handler(dev); + + sff_bus_master_reset(dev->bm[0]); + sff_bus_master_reset(dev->bm[1]); } static void @@ -731,27 +919,53 @@ sis_5511_close(void *priv) static void * sis_5511_init(UNUSED(const device_t *info)) { - sis_5511_t *dev = (sis_5511_t *) malloc(sizeof(sis_5511_t)); - memset(dev, 0, sizeof(sis_5511_t)); + sis_5511_t *dev = (sis_5511_t *) calloc(1, sizeof(sis_5511_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); - 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 */ + /* Device 0: SiS 5511 */ + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); + /* Device 1: SiS 5513 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot); + + /* SLiC Memory Mapped Registers */ + mem_mapping_add(&dev->slic_mapping, + 0xffc00000, 0x00001000, + sis_5511_slic_read, + NULL, + NULL, + sis_5511_slic_write, + NULL, + NULL, + NULL, MEM_MAPPING_EXTERNAL, + dev); + + /* Ports 22h-23h: SiS 5513 ISA */ + io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); /* MIRQ */ pci_enable_mirq(0); pci_enable_mirq(1); + /* IDEIRQ */ + pci_enable_mirq(2); + /* Port 92h */ dev->port_92 = device_add(&port_92_device); /* SFF IDE */ - dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); - dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + dev->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->bm[1] = device_add_inst(&sff8038i_device, 2); /* SMRAM */ dev->smram = smram_add(); + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); + sis_5511_reset(dev); return dev; diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 0e09de199..007a96178 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 Pentium PCI/ISA Chipset. * + * Authors: Miran Grca, * - * - * Authors: Tiseno100, - * - * Copyright 2021 Tiseno100. + * Copyright 2023-2024 Miran Grca. */ #include #include @@ -26,36 +24,26 @@ #include <86box/io.h> #include <86box/timer.h> -#include <86box/dma.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/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/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; @@ -75,50 +63,87 @@ sis_5571_log(const char *fmt, ...) #endif typedef struct sis_5571_t { - uint8_t pci_conf[256]; - uint8_t pci_conf_sb[3][256]; + uint8_t index; + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t pad; - int nb_pci_slot; - int sb_pci_slot; + uint8_t regs[16]; + uint8_t states[7]; + uint8_t pad0; - port_92_t *port_92; - sff8038i_t *ide_drive[2]; + uint8_t usb_unk_regs[8]; + + uint8_t pci_conf[256]; + uint8_t pci_conf_sb[3][256]; + + uint16_t usb_unk_base; + + sff8038i_t *bm[2]; smram_t *smram; + port_92_t *port_92; + void *pit; + nvr_t *nvr; usb_t *usb; - usb_params_t usb_params; - + uint8_t (*pit_read_reg)(void *priv, uint8_t reg); } sis_5571_t; static void -sis_5571_shadow_recalc(int cur_reg, sis_5571_t *dev) +sis_5571_shadow_recalc(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); + 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_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_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_log("%08X-%08X\n", base + 0x4000, base + 0x7fff); + } + } + + dev->states[i & 0x0f] = dev->pci_conf[i]; + } flushmmucache_nopc(); } static void -sis_5571_smm_recalc(sis_5571_t *dev) +sis_5571_smram_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); + switch (dev->pci_conf[0xa3] >> 6) { + case 0: + smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; - case 0x01: - smram_enable(dev->smram, 0xe0000, 0xa0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + case 1: + smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; - case 0x02: - smram_enable(dev->smram, 0xe0000, 0xb0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + case 2: + smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1); break; - case 0x03: - smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1); + case 3: + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1); break; default: @@ -128,580 +153,1012 @@ sis_5571_smm_recalc(sis_5571_t *dev) flushmmucache(); } -void -sis_5571_ide_handler(sis_5571_t *dev) +static void +sis_5571_mem_to_pci_reset(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(); - } - } -} + 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; -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); + 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 -memory_pci_bridge_write(UNUSED(int func), int addr, uint8_t val, void *priv) +sis_5571_mem_to_pci_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; - - 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_usb_update_interrupt(usb_t* usb, void* priv) -{ - const 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: + if (func == 0) { + sis_5571_log("SiS 5571 M2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val); + + switch (addr) { + 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; 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(UNUSED(usb_t* usb), UNUSED(void* priv)) +sis_5571_mem_to_pci_read(int func, int addr, void *priv) { - /* Left unimplemented for now. */ - return 1; + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) { + ret = dev->pci_conf[addr]; + + sis_5571_log("SiS 5571 M2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret); + } + + return ret; +} + +static void +sis_5571_pci_to_isa_reset(sis_5571_t *dev) +{ + /* 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][0x03] = 0x00; + dev->pci_conf_sb[0][0x04] = 0x07; + dev->pci_conf_sb[0][0x05] = 0x00; + dev->pci_conf_sb[0][0x06] = 0x00; + dev->pci_conf_sb[0][0x07] = 0x02; + dev->pci_conf_sb[0][0x08] = 0x01; + dev->pci_conf_sb[0][0x09] = 0x00; + dev->pci_conf_sb[0][0x0a] = 0x01; + dev->pci_conf_sb[0][0x0b] = 0x06; + dev->pci_conf_sb[0][0x0e] = 0x80; + + dev->pci_conf_sb[0][0x40] = 0x00; + dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80; + dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80; + dev->pci_conf_sb[0][0x45] = 0x00; + dev->pci_conf_sb[0][0x46] = 0x00; + dev->pci_conf_sb[0][0x47] = 0x00; + dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x00; + dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x00; + dev->pci_conf_sb[0][0x61] = 0x80; + dev->pci_conf_sb[0][0x62] = 0x00; + dev->pci_conf_sb[0][0x63] = 0x80; + dev->pci_conf_sb[0][0x64] = 0x00; + dev->pci_conf_sb[0][0x65] = 0x00; + dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00; + dev->pci_conf_sb[0][0x68] = 0x80; + dev->pci_conf_sb[0][0x69] = dev->pci_conf_sb[0][0x6a] = 0x00; + dev->pci_conf_sb[0][0x6b] = 0x00; + dev->pci_conf_sb[0][0x6c] = 0x02; + dev->pci_conf_sb[0][0x6d] = 0x00; + dev->pci_conf_sb[0][0x6e] = dev->pci_conf_sb[0][0x6f] = 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][0x75] = 0x00; + dev->pci_conf_sb[0][0x76] = dev->pci_conf_sb[0][0x77] = 0x00; + + 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_MIRQ1, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED); + pci_set_mirq_routing(PCI_MIRQ3, PCI_IRQ_DISABLED); + + cpu_set_isa_speed(7159091); + nvr_bank_set(0, 0, dev->nvr); +} + +static void +sis_5571_pci_to_isa_write(int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t old; + + sis_5571_log("SiS 5571 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command */ + // dev->pci_conf_sb[0][addr] = val & 0x0f; + break; + + case 0x07: /* Status */ + dev->pci_conf_sb[0][addr] &= ~(val & 0x30); + 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) ? PCI_IRQ_DISABLED : (val & 0x0f)); + break; + + case 0x45: + dev->pci_conf_sb[0][addr] = val & 0xec; + 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 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 0x60: + outb(0x0070, val); + break; + + /* Simply skip MIRQ0, so we can reuse the SiS 551x IDEIRQ infrastructure. */ + case 0x61: /* MIRQ Remapping Control Register */ + sis_5571_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + dev->pci_conf_sb[0][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_sb[0][addr] = val; + break; + + case 0x63: /* IDEIRQ Remapping Control Register */ + sis_5571_log("Set MIRQ routing: IDEIRQ -> %02X\n", val); + dev->pci_conf_sb[0][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_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 */ + sis_5571_log("Set MIRQ routing: USBIRQ -> %02X\n", val); + dev->pci_conf_sb[0][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_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 & 0x02; + break; + + case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */ + old = dev->pci_conf_sb[0][addr]; + picint((val ^ old) & val); + picintc((val ^ old) & ~val); + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */ + old = dev->pci_conf_sb[0][addr]; + picint(((val ^ old) & val) << 8); + picintc(((val ^ old) & ~val) << 8); + dev->pci_conf_sb[0][addr] = val; + break; + + case 0x70: + dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x02) | (val & 0xdc); + break; + + case 0x71: /* Type-F DMA Control Register */ + dev->pci_conf_sb[0][addr] = val & 0xef; + break; + + case 0x72: /* SMI Triggered By IRQ/GPIO Control */ + case 0x73: /* SMI Triggered By IRQ/GPIO Control */ + dev->pci_conf_sb[0][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_sb[0][addr] = val; + break; + } +} + +static uint8_t +sis_5571_pci_to_isa_read(int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + default: + ret = dev->pci_conf_sb[0][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: + ret = inb(0x0070); + break; + } + + sis_5571_log("SiS 5571 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5571_ide_irq_handler(sis_5571_t *dev) +{ + if (dev->pci_conf_sb[1][0x09] & 0x01) { + /* Primary IDE is native. */ + sis_5571_log("Primary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X); + } else { + /* Primary IDE is legacy. */ + sis_5571_log("Primary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); + } + + if (dev->pci_conf_sb[1][0x09] & 0x04) { + /* Secondary IDE is native. */ + sis_5571_log("Secondary IDE IRQ mode: Native, Native\n"); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X); + } else { + /* Secondary IDE is legacy. */ + sis_5571_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n"); + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + } +} + +static void +sis_5571_ide_handler(sis_5571_t *dev) +{ + uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01; + + uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe; + uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe; + uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe; + uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe; + + uint16_t current_pri_base; + uint16_t current_pri_side; + uint16_t current_sec_base; + uint16_t current_sec_side; + + /* Primary Channel Programming */ + current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr; + current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr; + + /* Secondary Channel Programming */ + current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr; + current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr; + + sis_5571_log("sis_5571_ide_handler(): Disabling primary IDE...\n"); + ide_pri_disable(); + sis_5571_log("sis_5571_ide_handler(): Disabling secondary IDE...\n"); + ide_sec_disable(); + + if (ide_io_on) { + /* Primary Channel Setup */ + if (dev->pci_conf_sb[1][0x4a] & 0x02) { + sis_5571_log("sis_5571_ide_handler(): Primary IDE base now %04X...\n", current_pri_base); + ide_set_base(0, current_pri_base); + sis_5571_log("sis_5571_ide_handler(): Primary IDE side now %04X...\n", current_pri_side); + ide_set_side(0, current_pri_side); + + sis_5571_log("sis_5571_ide_handler(): Enabling primary IDE...\n"); + ide_pri_enable(); + + sis_5571_log("SiS 5571 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side); + } + + /* Secondary Channel Setup */ + if (dev->pci_conf_sb[1][0x4a] & 0x04) { + sis_5571_log("sis_5571_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base); + ide_set_base(1, current_sec_base); + sis_5571_log("sis_5571_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side); + ide_set_side(1, current_sec_side); + + sis_5571_log("sis_5571_ide_handler(): Enabling secondary IDE...\n"); + ide_sec_enable(); + + sis_5571_log("SiS 5571: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side); + } + } + + sff_bus_master_handler(dev->bm[0], ide_io_on, + ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0); + sff_bus_master_handler(dev->bm[1], ide_io_on, + ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8); +} + +static void +sis_5571_ide_reset(sis_5571_t *dev) +{ + /* PCI IDE */ + 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][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; + dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00; + dev->pci_conf_sb[1][0x08] = 0xc0; + dev->pci_conf_sb[1][0x09] = 0x8a; + dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; + dev->pci_conf_sb[1][0x0e] = 0x80; + dev->pci_conf_sb[1][0x0f] = 0x00; + dev->pci_conf_sb[1][0x10] = 0xf1; + dev->pci_conf_sb[1][0x11] = 0x01; + dev->pci_conf_sb[1][0x14] = 0xf5; + dev->pci_conf_sb[1][0x15] = 0x03; + dev->pci_conf_sb[1][0x18] = 0x71; + dev->pci_conf_sb[1][0x19] = 0x01; + dev->pci_conf_sb[1][0x1c] = 0x75; + dev->pci_conf_sb[1][0x1d] = 0x03; + dev->pci_conf_sb[1][0x20] = 0x01; + dev->pci_conf_sb[1][0x21] = 0xf0; + dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00; + dev->pci_conf_sb[1][0x24] = dev->pci_conf_sb[1][0x25] = 0x00; + dev->pci_conf_sb[1][0x26] = dev->pci_conf_sb[1][0x27] = 0x00; + dev->pci_conf_sb[1][0x28] = dev->pci_conf_sb[1][0x29] = 0x00; + dev->pci_conf_sb[1][0x2a] = dev->pci_conf_sb[1][0x2b] = 0x00; +#ifdef DATASHEET + dev->pci_conf_sb[1][0x2c] = dev->pci_conf_sb[1][0x2d] = 0x00; +#else + /* The only Linux lspci listing I could find of this chipset, + shows a subsystem of 0058:0000. */ + dev->pci_conf_sb[1][0x2c] = 0x58; + dev->pci_conf_sb[1][0x2d] = 0x00; +#endif + dev->pci_conf_sb[1][0x2e] = dev->pci_conf_sb[1][0x2f] = 0x00; + dev->pci_conf_sb[1][0x30] = dev->pci_conf_sb[1][0x31] = 0x00; + dev->pci_conf_sb[1][0x32] = dev->pci_conf_sb[1][0x33] = 0x00; + dev->pci_conf_sb[1][0x40] = 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] = 0x06; + dev->pci_conf_sb[1][0x4b] = 0x00; + dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x00; + dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0x00; + + sis_5571_ide_irq_handler(dev); + sis_5571_ide_handler(dev); + + sff_bus_master_reset(dev->bm[0]); + sff_bus_master_reset(dev->bm[1]); +} + +static void +sis_5571_ide_write(int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + sis_5571_log("SiS 5571 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val); + + switch (addr) { + default: + break; + + case 0x04: /* Command low byte */ + dev->pci_conf_sb[1][addr] = val & 0x05; + sis_5571_ide_handler(dev); + break; + case 0x06: /* Status low byte */ + dev->pci_conf_sb[1][addr] = val & 0x20; + break; + case 0x07: /* Status high byte */ + dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38); + break; + case 0x09: /* Programming Interface Byte */ + dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x45); + sis_5571_ide_irq_handler(dev); + sis_5571_ide_handler(dev); + break; + case 0x0d: /* Latency Timer */ + dev->pci_conf_sb[1][addr] = val; + break; + + /* Primary Base Address */ + case 0x10: + case 0x11: + case 0x14: + case 0x15: + fallthrough; + + /* Secondary Base Address */ + case 0x18: + case 0x19: + case 0x1c: + case 0x1d: + fallthrough; + + /* Bus Mastering Base Address */ + case 0x20: + case 0x21: + if (addr == 0x20) + dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01; + else + dev->pci_conf_sb[1][addr] = val; + sis_5571_ide_handler(dev); + break; + + /* The only Linux lspci listing I could find of this chipset, + does not show any BIOS bar, therefore writes to that are disabled. */ +#ifdef DATASHEET + 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; +#endif + + case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */ + 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_sb[1][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 */ + case 0x49: /* IDE Command Active Time Control */ + dev->pci_conf_sb[1][addr] = val & 0x07; + 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 */ + dev->pci_conf_sb[1][addr] = val; + 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; + } +} + +static uint8_t +sis_5571_ide_read(int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + default: + ret = dev->pci_conf_sb[1][addr]; + break; + + case 0x09: + ret = dev->pci_conf_sb[1][addr]; + if (dev->pci_conf_sb[1][0x09] & 0x40) + ret |= ((dev->pci_conf_sb[1][0x4a] & 0x06) << 3); + break; + + case 0x3d: + ret = (dev->pci_conf_sb[1][0x09] & 0x05) ? PCI_INTA : 0x00; + break; + } + + sis_5571_log("SiS 5571 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret); + + return ret; +} + +/* SiS 5571 unknown I/O port (second USB PCI BAR). */ +static void +sis_5571_usb_unk_write(uint16_t addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + addr = (addr - dev->usb_unk_base) & 0x07; + + sis_5571_log("SiS 5571 USB UNK: [W] dev->usb_unk_regs[%02X] = %02X\n", addr, val); + + dev->usb_unk_regs[addr] = val; +} + +static uint8_t +sis_5571_usb_unk_read(uint16_t addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->usb_unk_base) & 0x07; + + ret = dev->usb_unk_regs[addr & 0x07]; + + sis_5571_log("SiS 5571 USB UNK: [R] dev->usb_unk_regs[%02X] = %02X\n", addr, ret); + + return ret; +} + +static void +sis_5571_usb_reset(sis_5571_t *dev) +{ + /* USB */ + 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][0x04] = dev->pci_conf_sb[1][0x05] = 0x00; + dev->pci_conf_sb[2][0x06] = 0x00; + dev->pci_conf_sb[2][0x07] = 0x02; + 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] = 0x0c; + dev->pci_conf_sb[2][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00; + dev->pci_conf_sb[2][0x0e] = 0x80 /* 0x10 - Datasheet erratum - header type 0x10 is invalid! */; + dev->pci_conf_sb[2][0x0f] = 0x00; + dev->pci_conf_sb[2][0x10] = 0x00; + dev->pci_conf_sb[2][0x11] = 0x00; + dev->pci_conf_sb[2][0x12] = 0x00; + dev->pci_conf_sb[2][0x13] = 0x00; + dev->pci_conf_sb[2][0x14] = 0x01; + dev->pci_conf_sb[2][0x15] = 0x00; + dev->pci_conf_sb[2][0x16] = 0x00; + dev->pci_conf_sb[2][0x17] = 0x00; + dev->pci_conf_sb[2][0x3c] = 0x00; + dev->pci_conf_sb[2][0x3d] = PCI_INTA; + dev->pci_conf_sb[2][0x3e] = 0x00; + dev->pci_conf_sb[2][0x3f] = 0x00; + + 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][0x04] & 0x02); + + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_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_5571_usb_write(int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *) priv; + + sis_5571_log("SiS 5571 USB: [W] dev->pci_conf_sb[2][%02X] = %02X\n", addr, val); + + if (dev->pci_conf_sb[0][0x68] & 0x40) switch (addr) { + default: + break; + + case 0x04: /* Command - Low Byte */ + dev->pci_conf_sb[2][addr] = val & 0x47; + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_usb_unk_write, NULL, NULL, dev); + if (dev->pci_conf_sb[2][0x04] & 0x01) + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_usb_unk_write, NULL, NULL, dev); + } + 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][0x04] & 0x02); + break; + + case 0x05: /* Command - High Byte */ + dev->pci_conf_sb[2][addr] = val & 0x01; + break; + + case 0x07: /* Status - High Byte */ + dev->pci_conf_sb[2][addr] &= ~(val & 0xf9); + break; + + case 0x0d: /* Latency Timer */ + dev->pci_conf_sb[2][addr] = val; + break; + + 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) ? 0xf0 : 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] & 0x02); + break; + + case 0x14: /* IO Space Base Address Register */ + case 0x15: /* IO Space Base Address Register */ + if (dev->usb_unk_base != 0x0000) { + io_removehandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_usb_unk_write, NULL, NULL, dev); + } + dev->pci_conf_sb[2][addr] = val; + dev->usb_unk_base = (dev->pci_conf_sb[2][0x14] & 0xf8) | + (dev->pci_conf_sb[2][0x15] << 8); + if (dev->usb_unk_base != 0x0000) { + io_sethandler(dev->usb_unk_base, 0x0002, + sis_5571_usb_unk_read, NULL, NULL, + sis_5571_usb_unk_write, NULL, NULL, dev); + } + break; + + case 0x3c: /* Interrupt Line */ + dev->pci_conf_sb[2][addr] = val; + break; + } +} + +static uint8_t +sis_5571_usb_read(int addr, void *priv) +{ + const sis_5571_t *dev = (sis_5571_t *) priv; + uint8_t ret = 0xff; + + if (dev->pci_conf_sb[0][0x68] & 0x40) { + ret = dev->pci_conf_sb[2][addr]; + + sis_5571_log("SiS 5571 USB: [R] dev->pci_conf_sb[2][%02X] = %02X\n", addr, ret); + } + + return ret; +} + +static void +sis_5571_sb_write(int func, int addr, uint8_t val, void *priv) +{ + switch (func) { + case 0x00: + sis_5571_pci_to_isa_write(addr, val, priv); + break; + case 0x01: + sis_5571_ide_write(addr, val, priv); + break; + case 0x02: + sis_5571_usb_write(addr, val, priv); + break; + } +} + +static uint8_t +sis_5571_sb_read(int func, int addr, void *priv) +{ + uint8_t ret = 0xff; + + switch (func) { + case 0x00: + ret = sis_5571_pci_to_isa_read(addr, priv); + break; + case 0x01: + ret = sis_5571_ide_read(addr, priv); + break; + case 0x02: + ret = sis_5571_usb_read(addr, priv); + break; + } + + return ret; } static void @@ -710,52 +1167,16 @@ 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; + sis_5571_mem_to_pci_reset(dev); /* 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; + sis_5571_pci_to_isa_reset(dev); /* 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); + sis_5571_ide_reset(dev); /* 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; + sis_5571_usb_reset(dev); } static void @@ -770,28 +1191,43 @@ sis_5571_close(void *priv) 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)); + sis_5571_t *dev = (sis_5571_t *) calloc(1, sizeof(sis_5571_t)); + uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1)); - 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); + /* Device 0: Memory/PCI Bridge */ + pci_add_card(PCI_ADD_NORTHBRIDGE, + sis_5571_mem_to_pci_read, sis_5571_mem_to_pci_write, dev, &dev->nb_slot); + /* Device 1: Southbridge */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5571_sb_read, sis_5571_sb_write, dev, &dev->sb_slot); /* MIRQ */ - pci_enable_mirq(0); + pci_enable_mirq(1); - /* Port 92 & SMRAM */ - dev->port_92 = device_add(&port_92_pci_device); - dev->smram = smram_add(); + /* IDEIRQ */ + pci_enable_mirq(2); + + /* USBIRQ */ + pci_enable_mirq(3); + + /* Port 92h */ + dev->port_92 = device_add(&port_92_device); /* SFF IDE */ - dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1); - dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); + dev->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->bm[1] = device_add_inst(&sff8038i_device, 2); + + /* SMRAM */ + dev->smram = smram_add(); + + /* PIT */ + dev->pit = device_find_first_priv(DEVICE_PIT); + dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg; + + /* NVR */ + dev->nvr = device_add(&at_mb_nvr_device); /* 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->usb = device_add(&usb_device); sis_5571_reset(dev); diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 8aac6ecd5..4d1db2d9e 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 @@ -45,9 +46,13 @@ typedef struct sis_85c496_t { 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]; @@ -612,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); @@ -648,7 +653,7 @@ 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); #if 0 sis_85c497_isa_reset(dev); diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index 97c989b73..cf4ff42d7 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -176,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; diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 00556c6f0..7f4aebb7c 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -59,6 +59,10 @@ sis_85c50x_log(const char *fmt, ...) typedef struct sis_85c50x_t { uint8_t index; + uint8_t nb_slot; + uint8_t sb_slot; + uint8_t pad; + uint8_t pci_conf[256]; uint8_t pci_conf_sb[256]; uint8_t regs[256]; @@ -426,10 +430,10 @@ sis_85c50x_init(UNUSED(const device_t *info)) memset(dev, 0x00, sizeof(sis_85c50x_t)); /* 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(); diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index 092c0ae32..dbe39ec5c 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -45,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) */ @@ -54,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 { @@ -893,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) -{ - const 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) { @@ -926,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); diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index c612e1974..f6a923346 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -121,8 +121,13 @@ umc_8886_log(const char *fmt, ...) #define SB_ID dev->sb_id typedef struct umc_8886_t { - uint8_t max_func; /* Last function number */ - uint8_t pci_conf_sb[2][256]; /* PCI Registers */ + uint8_t max_func; /* Last function number */ + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + + uint8_t pci_conf_sb[2][256]; /* PCI Registers */ + uint16_t sb_id; /* Southbridge Revision */ int has_ide; /* Check if Southbridge Revision is AF or F */ } umc_8886_t; @@ -202,7 +207,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) case 0x56: dev->pci_conf_sb[func][addr] = val; - switch (val & 2) { + switch (val & 3) { case 0: cpu_set_isa_pci_div(3); break; @@ -371,7 +376,7 @@ umc_8886_init(const device_t *info) 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 */ + pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Device 12: UMC 8886xx */ /* Add IDE if UM8886AF variant */ if (HAS_IDE) diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index 60b070f0b..d5cce0fca 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -103,25 +103,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 @@ -146,6 +132,8 @@ typedef struct hb4_t { uint8_t shadow; uint8_t shadow_read; uint8_t shadow_write; + uint8_t pci_slot; + uint8_t pci_conf[256]; /* PCI Registers */ int mem_state[9]; smram_t *smram[3]; /* SMRAM Handlers */ @@ -393,7 +381,7 @@ 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); diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index bd4445521..7c1203c3a 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; @@ -715,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; diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index ab109ef4b..1f153092b 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,7 @@ #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> @@ -116,9 +113,10 @@ typedef struct { } pipc_io_trap_t; typedef struct _pipc_ { - uint32_t local; 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]; @@ -128,10 +126,11 @@ typedef struct _pipc_ { uint8_t fmnmi_regs[4]; uint8_t fmnmi_status; + uint32_t local; + sff8038i_t *bm[2]; nvr_t *nvr; int nvr_enabled; - int slot; ddma_t *ddma; smbus_piix4_t *smbus; usb_t *usb[2]; @@ -211,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); @@ -238,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; @@ -567,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 @@ -1093,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; @@ -1474,9 +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); -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x90: case 0x91: @@ -1619,6 +1614,14 @@ pipc_reset(void *priv) 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); + + 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 * @@ -1630,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); @@ -1664,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); @@ -1694,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); diff --git a/src/chipset/via_vt82c49x.c b/src/chipset/via_vt82c49x.c index e25fdbfa0..de55f7060 100644 --- a/src/chipset/via_vt82c49x.c +++ b/src/chipset/via_vt82c49x.c @@ -30,6 +30,7 @@ #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> diff --git a/src/chipset/via_vt82c505.c b/src/chipset/via_vt82c505.c index 136d335c7..34efbead9 100644 --- a/src/chipset/via_vt82c505.c +++ b/src/chipset/via_vt82c505.c @@ -32,6 +32,10 @@ typedef struct vt82c505_t { uint8_t index; + uint8_t pci_slot; + uint8_t pad; + uint8_t pad0; + uint8_t pci_conf[256]; } vt82c505_t; @@ -203,7 +207,7 @@ 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/codegen/codegen.c b/src/codegen/codegen.c index f2d678067..79b26015c 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 ddcf5095f..6d30211a6 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 894ebb100..a81eef67e 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" diff --git a/src/codegen/codegen_ops_arith.h b/src/codegen/codegen_ops_arith.h index e6561208e..28ee6d06c 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 323a25542..1021cc742 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 f5c66dd1b..da16ce03e 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 d0216644c..9f23723e2 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 e667bc40e..4c5a92c8f 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 265369771..342ddedd4 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 18480a6b5..bc6293c0b 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 80e081220..410ce8e17 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(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(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(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(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 820d4461a..28a558078 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 3934b4ac5..421f20026 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 * diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index 712fbe087..456f93ae9 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 * diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index b0250fb7d..a3f4ede8f 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; @@ -637,7 +650,7 @@ generate_call: if (!fpu_softfloat && recomp_opcodes_3DNOW[opcode_3dnow]) { next_pc = opcode_pc + 1; - op_table = (OpFn *) x86_dynarec_opcodes_3DNOW; + op_table = x86_dynarec_opcodes_3DNOW; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_3DNOW; opcode = opcode_3dnow; recomp_opcode_mask = 0xff; @@ -646,8 +659,10 @@ generate_call: } 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 @@ generate_call: // 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 @@ generate_call: 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 @@ generate_call: 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 547f867e3..deeeb899c 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 d9ae38af8..29b05ad77 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 9661cf631..90e619d70 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 a389f239f..b1e904096 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 48d949406..1eb94a909 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 6e5034cc0..88d28aee0 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 aa5e5870a..915cae93d 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 91fb9c903..7514e1f0c 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 e56b2f6e5..3331af4e0 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 d0b8b86c1..338d3dd54 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 a57cb4282..3cbca28f8 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 33fb500db..236a86ce7 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 42c2d5259..b5d146439 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 f15b1aee4..caa925fc0 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 e9c08cbc8..fcab0f3ce 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 f656e708f..18235e2b2 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 4807caacf..90e59dcb0 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 13f90743a..7f4735124 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 0a6469a89..f0da3ff64 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 a1e04db30..084e04a87 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 00ae453c3..5ef2d97b8 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 3a1a5e1ab..ee0a030ba 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 44689a5d1..6345bbe86 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 ae93aa80f..59e148659 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -604,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 352d95f13..a91382c2f 100644 --- a/src/codegen_new/codegen_ops.h +++ b/src/codegen_new/codegen_ops.h @@ -19,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 c2b04584c..8b4d471ba 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 5325b282b..9e136ace5 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 9a6722342..cedb54177 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) +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) +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 98d77250c..3ab7be8ac 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 89c138637..862845868 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 06709913d..7635063e8 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 cca9f4e4f..7865e0573 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 242cbb818..f2a4ce41a 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 0bd4db24a..fb2f1e5ba 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 6db452a45..684052fea 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 9a23536ed..545634672 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 b352c402a..e99b4c56d 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 c8d4909f9..6f38cba67 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 a20e18e68..9d37228ec 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 664bfd14c..dd50b486e 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 99016352e..d25edd52e 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 32449d188..b812a9bb2 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 68e8fb011..eae7045a8 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 8ccf7d9e7..0daebff67 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 b7afdce25..92ad9509d 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 63277690f..a3f000826 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 c106349f5..ebb90b42f 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 d917d4548..c973abf23 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; @@ -144,15 +139,12 @@ load_general(void) rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); 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"); + status_icons_fullscreen = !!ini_section_get_int(cat, "status_icons_fullscreen", 0); + window_remember = ini_section_get_int(cat, "window_remember", 0); + + 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 +205,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]; - const 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,205 +243,29 @@ static void load_machine(void) { ini_section_t cat = ini_find_section(config, "Machine"); - char *p; - const char *migrate_from = NULL; + const char *p; 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 { - machine = machine_get_machine_from_internal_name(p); - migrate_from = NULL; - } - } else + if (p != NULL) + machine = machine_get_machine_from_internal_name(p); + 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; - /* Copy NVR files when migrating a machine to a new internal name. */ - if (migrate_from) { - char old_fn[256]; - strcpy(old_fn, migrate_from); - strcat(old_fn, "."); - c = strlen(old_fn); - char new_fn[256]; - strcpy(new_fn, machines[machine].internal_name); - strcat(new_fn, "."); - i = strlen(new_fn); - - /* Iterate through NVR files. */ - DIR *dirp = opendir(nvr_path(".")); - if (dirp) { - struct dirent *entry; - while ((entry = readdir(dirp))) { - /* Check if this file corresponds to the old name. */ - if (strncmp(entry->d_name, old_fn, c)) - continue; - - /* Add extension to the new name. */ - strcpy(&new_fn[i], &entry->d_name[c]); - - /* Only copy if a file with the new name doesn't already exist. */ - FILE *g = nvr_fopen(new_fn, "rb"); - if (!g) { - FILE *f = nvr_fopen(entry->d_name, "rb"); - g = nvr_fopen(new_fn, "wb"); - - uint8_t buf[4096]; - while ((j = fread(buf, 1, sizeof(buf), f))) - fwrite(buf, 1, j, g); - - fclose(f); - } - fclose(g); - } - } - } - cpu_override = ini_section_get_int(cat, "cpu_override", 0); 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"); - else - cpu_f = cpu_get_family(p); + 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", 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 +277,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 +307,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; } @@ -504,18 +322,13 @@ load_machine(void) 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); - if (machine_has_flags(machine, MACHINE_SOFTFLOAT_ONLY)) + if ((fpu_type != FPU_NONE) && machine_has_flags(machine, MACHINE_SOFTFLOAT_ONLY)) fpu_softfloat = 1; p = ini_section_get_string(cat, "time_sync", NULL); @@ -532,10 +345,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. */ @@ -561,17 +370,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); @@ -599,55 +414,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); @@ -666,7 +471,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]); } } } @@ -773,50 +579,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++; } @@ -826,54 +628,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)); } } @@ -893,12 +691,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); -#if 0 - 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); -#endif - sprintf(temp, "serial%d_passthrough_enabled", c + 1); serial_passthrough_enabled[c] = !!ini_section_get_int(cat, temp, 0); @@ -935,17 +727,6 @@ load_storage_controllers(void) 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); @@ -1027,27 +808,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]); + } } } @@ -1105,6 +878,7 @@ load_hard_disks(void) break; case HDD_BUS_SCSI: + case HDD_BUS_ATAPI: max_spt = 255; max_hpc = 255; max_tracks = 266305; @@ -1122,6 +896,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: @@ -1154,7 +930,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); @@ -1198,34 +974,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); @@ -1260,70 +1026,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 0 - if (*wp != L'\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); - 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) @@ -1338,9 +1040,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); @@ -1352,30 +1051,22 @@ 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 0 - if (*wp != L'\0') + 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); @@ -1385,7 +1076,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); @@ -1407,11 +1099,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]); } } } @@ -1493,24 +1194,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; @@ -1518,6 +1214,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); @@ -1534,19 +1248,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); - } - } } } @@ -1557,94 +1267,11 @@ load_other_removable_devices(void) ini_section_t cat = ini_find_section(config, "Other removable devices"); char temp[512]; char tmp2[512]; - const char *p; + char *p; char s[512]; 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++) { @@ -1705,26 +1332,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); @@ -1740,10 +1381,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)); @@ -1805,9 +1448,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); @@ -1823,10 +1497,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); + } + } } } @@ -1837,62 +1513,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); @@ -1935,6 +1559,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"); @@ -1983,9 +1608,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,8 +1620,6 @@ 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 */ @@ -2089,12 +1712,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) { @@ -2165,6 +1785,11 @@ save_general(void) else ini_section_delete_var(cat, "open_dir_usr_path"); + if (status_icons_fullscreen) + ini_section_set_int(cat, "status_icons_fullscreen", status_icons_fullscreen); + else + ini_section_delete_var(cat, "status_icons_fullscreen"); + if (video_framerate != -1) ini_section_set_int(cat, "video_gl_framerate", video_framerate); else @@ -2178,6 +1803,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 +1815,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"); @@ -2227,7 +1856,7 @@ save_machine(void) ini_section_set_string(cat, "machine", p); ini_section_set_string(cat, "cpu_family", cpu_f->internal_name); - ini_section_set_int(cat, "cpu_speed", cpu_f->cpus[cpu].rspeed); + 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); @@ -2258,12 +1887,15 @@ save_machine(void) /* 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 */ + 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 */ + } else if ((legacy_table_entry->rspeed >= cpu_f->cpus[cpu].rspeed) && + (closest_legacy_cpu == -1)) + /* Closest speed match. */ closest_legacy_cpu = i; - } } i++; @@ -2296,7 +1928,8 @@ save_machine(void) else 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 +1966,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 +2136,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; @@ -2538,24 +2173,21 @@ save_network(void) } 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 { -#if 0 - ini_section_set_string(cat, temp, "none"); -#endif + 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); @@ -2577,21 +2209,6 @@ save_ports(void) else ini_section_set_int(cat, temp, com_ports[c].enabled); -#if 0 - 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)); -#endif - sprintf(temp, "serial%d_passthrough_enabled", c + 1); if (serial_passthrough_enabled[c]) { ini_section_set_int(cat, temp, 1); @@ -2732,6 +2349,11 @@ 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) @@ -2790,9 +2412,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); } @@ -2833,7 +2455,8 @@ 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, hdd_preset_get_internal_name(hdd[c].speed_preset)); @@ -2868,7 +2491,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); @@ -2891,48 +2518,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) { + 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; - } + 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); @@ -2960,18 +2586,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]); } } } @@ -3020,10 +2654,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); } } @@ -3059,10 +2697,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); } } @@ -3072,9 +2714,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 87d481e1f..f89a8dc96 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -12,17 +12,24 @@ #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/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 +40,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 +61,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 +73,162 @@ x386_log(const char *fmt, ...) #define getword2f() \ ((uint16_t) (fetchdat >> 8)); \ cpu_state.pc += 2 -*/ -#define OP_TABLE(name) ops_##name +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; -#if 0 -# define CLOCK_CYCLES(c) \ - { \ - if (fpu_cycles > 0) { \ - fpu_cycles -= (c); \ - if (fpu_cycles < 0) { \ - cycles += fpu_cycles; \ - } \ - } else { \ - cycles -= (c); \ - } \ + 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; @@ -180,11 +257,13 @@ 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)); 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; @@ -212,7 +291,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 +299,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(); @@ -263,7 +342,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 +352,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 +369,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 760e41eaa..60ecd8954 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,16 +69,60 @@ 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; +int smm_in_hlt = 0; +int smi_block = 0; -uint32_t addr64, addr64_2; -uint32_t addr64a[8], addr64a_2[8]; +int prefetch_prefixes = 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 */ + +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; @@ -321,6 +375,77 @@ x386_common_log(const char *fmt, ...) # define x386_common_log(fmt, ...) #endif +/*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 +516,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 +608,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 +719,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 +803,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 +908,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 +991,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 +1090,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 +1114,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 +1166,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 +1186,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 +1244,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 +1304,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 +1322,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 +1343,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 +1411,7 @@ x86_int(int num) cpu_state.pc = cpu_state.oldpc; if (msw & 1) - pmodeint(num, 0); + is486 ? pmodeint(num, 0) : pmodeint_2386(num, 0); else { addr = (num << 2) + idt.base; @@ -1325,7 +1444,7 @@ x86_int(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); } } @@ -1342,7 +1461,7 @@ x86_int_sw(int num) cycles -= timing_int; if (msw & 1) - pmodeint(num, 1); + is486 ? pmodeint(num, 1) : pmodeint_2386(num, 1); else { addr = (num << 2) + idt.base; @@ -1367,7 +1486,7 @@ x86_int_sw(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); cycles -= timing_int_rm; } } @@ -1380,7 +1499,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,7 +1528,7 @@ x86_int_sw_rm(int num) cpu_state.eflags &= ~VIF_FLAG; cpu_state.flags &= ~T_FLAG; cpu_state.pc = new_pc; - loadcs(new_cs); + is486 ? loadcs(new_cs) : loadcs_2386(new_cs); #ifndef USE_NEW_DYNAREC oxpc = cpu_state.pc; #endif @@ -1468,8 +1588,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 +1617,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(); diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 8cad28ae7..22fbd4bff 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -20,83 +20,112 @@ #define _386_COMMON_H_ #include - #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)))) +#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) \ - 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 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) \ - 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_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) \ - 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) +# 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,47 @@ 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) +{ + return readmembl_2386(a); +} + +static __inline uint16_t +fastreadw(uint32_t a) +{ + return readmemwl_2386(a); +} + +static __inline uint32_t +fastreadl(uint32_t a) +{ + return readmemll_2386(a); +} +#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 +274,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 +305,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 +338,37 @@ 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 val; + + if ((a & 0xFFF) > 0xFFE) { + val = fastreadb(a); + if (opcode_length[val & 0xff] > 1) + val |= ((uint16_t) fastreadb(a + 1) << 8); + return val; + } + + return readmemwl_2386(a); +} + +static __inline uint32_t +fastreadl_fetch(uint32_t a) +{ + uint32_t val; + + if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) { + val = fastreadw_fetch(a); + if (opcode_length[val & 0xff] > 2) + val |= ((uint32_t) fastreadw(a + 2) << 16); + return val; + } + + return readmemll_2386(a); +} +#else static __inline uint16_t fastreadw_fetch(uint32_t a) { @@ -300,22 +381,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 +412,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 +453,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 +613,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 + 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); +# 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)); \ diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index d7b3751b2..e4caa8a1b 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,8 @@ #define CPU_BLOCK_END() cpu_block_end = 1 -int inrecomp = 0, cpu_block_end = 0; +int inrecomp = 0; +int cpu_block_end = 0; int cpu_end_block_after_ins = 0; #ifdef ENABLE_386_DYNAREC_LOG @@ -183,78 +186,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 +226,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 +258,7 @@ update_tsc(void) if (cycdiff > 0) { if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); + timer_process(); } } @@ -406,8 +337,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 @@ -556,7 +488,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; @@ -640,7 +574,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 +676,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; @@ -845,7 +784,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 +797,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 f3e2f6e6e..77b72ef59 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 91449efeb..8a0f4cd5a 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -173,13 +173,14 @@ 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" +#ifndef OPS_286_386 +# include "x86_ops_cyrix.h" +#endif #include "x86_ops_flag.h" #include "x86_ops_fpu.h" #include "x86_ops_inc_dec.h" @@ -188,38 +189,53 @@ extern void x386_dynarec_log(const char *fmt, ...); #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" #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 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 #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) { @@ -331,7 +347,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) { @@ -376,6 +439,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 @@ -745,6 +809,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*/ @@ -928,6 +993,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 @@ -1021,6 +1087,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*/ @@ -1297,7 +1364,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*/ @@ -1389,7 +1456,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 @@ -1667,7 +1734,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*/ @@ -1759,7 +1826,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 @@ -2036,6 +2103,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 6f3dd4267..7a7e7b96c 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 e0419a9f7..3572f2c9f 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -70,38 +70,6 @@ static int in_rep = 0, repeating = 0, rep_c_flag = 0; static int oldc, clear_lock = 0; static int refresh = 0, cycdiff; -static int access_code = 0; -static int hlda = 0; -static int not_ready = 0; -static int bus_request_type = 0; -static int pic_data = -1; -static int last_was_code = 0; -static uint16_t mem_data = 0; -static uint32_t mem_seg = 0; -static uint16_t mem_addr = 0; -static int schedule_fetch = 1; -static int pasv = 0; - -#define BUS_OUT 1 -#define BUS_HIGH 2 -#define BUS_WIDE 4 -#define BUS_CODE 8 -#define BUS_IO 16 -#define BUS_MEM 32 -#define BUS_PIC 64 -#define BUS_ACCESS_TYPE (BUS_CODE | BUS_IO | BUS_MEM | BUS_PIC) - -#define BUS_CYCLE (biu_cycles & 3) -#define BUS_CYCLE_T1 biu_cycles = 0 -#define BUS_CYCLE_NEXT biu_cycles = (biu_cycles + 1) & 3 - -enum { - BUS_T1 = 0, - BUS_T2, - BUS_T3, - BUS_T4 -}; - /* Various things needed for 8087. */ #define OP_TABLE(name) ops_##name @@ -183,7 +151,7 @@ x808x_log(const char *fmt, ...) # define x808x_log(fmt, ...) #endif -static void pfq_add(void); +static void pfq_add(int c, int add); static void set_pzs(int bits); uint16_t @@ -204,344 +172,62 @@ 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 * ((uint64_t) xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) timer_process(); } static void -process_timers(void) -{ - clock_end(); - clock_start(); -} - -static void -cycles_forward(int c) +fetch_and_bus(int c, int bus) { - cycles -= c; + if (refresh > 0) { + /* Finish the current fetch, if any. */ + cycles -= ((4 - (biu_cycles & 3)) & 3); + pfq_add((4 - (biu_cycles & 3)) & 3, 1); + /* Add 4 memory access cycles. */ + cycles -= 4; + pfq_add(4, 0); - if (!is286) - process_timers(); -} - -static void -bus_outb(uint16_t port, uint8_t val) -{ - int old_cycles = cycles; - - cycles--; - outb(port, val); - resub_cycles(old_cycles); -} - -static void -bus_outw(uint16_t port, uint16_t val) -{ - int old_cycles = cycles; - - cycles--; - outw(port, val); - resub_cycles(old_cycles); -} - -static uint8_t -bus_inb(uint16_t port) -{ - int old_cycles = cycles; - uint8_t ret; - - cycles--; - ret = inb(port); - resub_cycles(old_cycles); - - return ret; -} - -static uint16_t -bus_inw(uint16_t port) -{ - int old_cycles = cycles; - uint16_t ret; - - cycles--; - ret = inw(port); - resub_cycles(old_cycles); - - return ret; -} - -static void -bus_do_io(int io_type) -{ - last_was_code = 0; - - x808x_log("(%02X) bus_do_io(%02X): %04X\n", opcode, io_type, cpu_state.eaaddr); - - if (io_type & BUS_OUT) { - if (io_type & BUS_WIDE) - bus_outw((uint16_t) cpu_state.eaaddr, AX); - else if (io_type & BUS_HIGH) - bus_outb(((uint16_t) cpu_state.eaaddr + 1) & 0xffff, AH); - else - bus_outb((uint16_t) cpu_state.eaaddr, AL); - } else { - if (io_type & BUS_WIDE) - AX = bus_inw((uint16_t) cpu_state.eaaddr); - else if (io_type & BUS_HIGH) - AH = bus_inb(((uint16_t) cpu_state.eaaddr + 1) & 0xffff); - else - AL = bus_inb((uint16_t) cpu_state.eaaddr); - } - - process_timers(); -} - -static void -bus_writeb(uint32_t seg, uint32_t addr, uint8_t val) -{ - write_mem_b(seg + addr, val); -} - -static void -bus_writew(uint32_t seg, uint32_t addr, uint16_t val) -{ - write_mem_w(seg + addr, val); -} - -static uint8_t -bus_readb(uint32_t seg, uint32_t addr) -{ - uint8_t ret = read_mem_b(seg + addr); - - return ret; -} - -static uint16_t -bus_readw(uint32_t seg, uint32_t addr) -{ - uint16_t ret = read_mem_w(seg + addr); - - return ret; -} - -static void -bus_do_mem(int io_type) -{ - last_was_code = 0; - - if (io_type & BUS_OUT) { - if (io_type & BUS_WIDE) - bus_writew(mem_seg, (uint32_t) mem_addr, mem_data); - else if (io_type & BUS_HIGH) { - if (is186 && !is_nec) - bus_writeb(mem_seg, ((uint32_t) mem_addr) + 1, mem_data >> 8); - else - bus_writeb(mem_seg, (uint32_t) ((mem_addr + 1) & 0xffff), mem_data >> 8); - } else - bus_writeb(mem_seg, (uint32_t) mem_addr, mem_data & 0xff); - } else { - if (io_type & BUS_WIDE) - mem_data = bus_readw(mem_seg, (uint32_t) mem_addr); - else if (io_type & BUS_HIGH) { - if (is186 && !is_nec) - mem_data = (mem_data & 0x00ff) | (((uint16_t) bus_readb(mem_seg, ((uint32_t) mem_addr) + 1)) << 8); - else - mem_data = (mem_data & 0x00ff) | (((uint16_t) bus_readb(mem_seg, (uint32_t) ((mem_addr + 1) & 0xffff))) << 8); - } else - mem_data = (mem_data & 0xff00) | ((uint16_t) bus_readb(mem_seg, (uint32_t) mem_addr)); - } -} - -static void -run_bus_cycle(int io_type) -{ - int do_bus_access = (io_type != 0) && (!(io_type & BUS_CODE) || schedule_fetch); - - x808x_log("[%04X:%04X] %02X bus access %02X (%i)\n", CS, cpu_state.pc, opcode, io_type, do_bus_access); - - if (do_bus_access) { - if (not_ready > 0) { - x808x_log("[%04X:%04X] %02X TW x%i\n", CS, cpu_state.pc, opcode, not_ready); - cycles_forward(not_ready); - not_ready = 0; - } - - switch(BUS_CYCLE) { - case BUS_T1: - access_code = !!(io_type & BUS_CODE); - break; - case BUS_T3: - switch (io_type & BUS_ACCESS_TYPE) { - case BUS_CODE: - pfq_add(); - last_was_code = 1; - break; - case BUS_IO: - bus_do_io(io_type); - break; - case BUS_MEM: - bus_do_mem(io_type); - break; - case BUS_PIC: - pic_data = pic_irq_ack(); - last_was_code = 0; - break; - default: - break; - } - break; - default: - break; - } - } -} - -static void -run_dma_cycle(int idle) -{ - if (not_ready > 0) { - /* Subtract one not ready cycle. */ - not_ready--; - } else if (hlda > 0) { - hlda--; - /* DMAWAIT is two cycles in, the actual wait states - are inserted with one cycle of delay. */ - if (hlda == 0) { - /* Deassert READY. */ - not_ready = 6; - } - } else if ((refresh > 0) && (in_lock == 0) && (idle || (BUS_CYCLE >= BUS_T3))) { - /* Refresh pending and it's either non-bus cycle or T3-T4, - raise HLDA. */ - hlda = 2; - /* Decrease the refresh count. */ refresh--; } -} -static void -cycles_idle(int c) -{ - int d; - - for (d = 0; d < c; d++) { - x808x_log("[%04X:%04X] %02X TI\n", CS, cpu_state.pc, opcode); - - cycles_forward(1); - run_dma_cycle(1); + pfq_add(c, !bus); + if (bus < 2) { + clock_end(); + clock_start(); } } -static void -cycles_biu(int bus, int init) -{ - /* T1, T2 = Nothing, T3 = Start and schedule, T4 = Nothing */ - pasv = (bus || ((BUS_CYCLE == BUS_T1) && schedule_fetch)) ? 0 : 1; - - x808x_log("cycles_biu(%i, %i): %i, %i, %i, %i\n", bus, init, prefetching, pfq_pos, pfq_size, BUS_CYCLE); - if (bus) { - /* CPU wants non-code bus access. */ - if (init) { - if (schedule_fetch) { - switch (BUS_CYCLE) { - case BUS_T1: - case BUS_T2: - BUS_CYCLE_T1; /* Simply abort the prefetch before actual scheduling, no penalty. */ - break; - case BUS_T3: - case BUS_T4: - cycles_idle(5 - BUS_CYCLE); /* Leftover BIU cycles + 2 idle cycles. */ - BUS_CYCLE_T1; /* Abort the prefetch. */ - break; - } - - schedule_fetch = 0; - access_code = 0; - } - } - - run_bus_cycle(bus_request_type); - } else { - /* CPU wants idle or code bus access. */ - if (schedule_fetch) - run_bus_cycle(BUS_CODE); - } - - if (BUS_CYCLE == BUS_T3) - schedule_fetch = prefetching && (pfq_pos < pfq_size); - - run_dma_cycle(pasv); - - BUS_CYCLE_NEXT; -} - -#ifdef REENIGNE_MODELING -static void -bus_init(void) -{ - /* Replacement for the old access() stuff. */ - if ((BUS_CYCLE == BUS_T4) && last_was_code && (opcode != 0x8f) && (opcode != 0xc7) && (opcode != 0xcc) && (opcode != 0xcd) && (opcode != 0xce) && ((opcode & 0xf0) != 0xa0)) - cycles_idle(1); - - cycles_idle(2); - - while ((BUS_CYCLE == BUS_T2) || (BUS_CYCLE == BUS_T3)) - cycles_idle(1); -} -#endif - -/* Bus: - 0 CPU cycles without bus access. - 1 CPU cycle T1-T4, bus access. - 2 CPU cycle Tw (wait state). - 3 CPU cycle Ti (idle). - */ static void wait(int c, int bus) { - int d; - - if (c < 0) - pclog("Negative cycles: %i!\n", c); - - x808x_log("[%04X:%04X] %02X %i cycles (%i)\n", CS, cpu_state.pc, opcode, c, bus); - - for (d = 0; d < c; d++) { - x808x_log("[%04X:%04X] %02X cycle %i BIU\n", CS, cpu_state.pc, opcode, d); - cycles_biu(bus, !d); - x808x_log("[%04X:%04X] %02X cycle %i EU\n", CS, cpu_state.pc, opcode, d); - cycles_forward(1); - } + cycles -= c; + fetch_and_bus(c, bus); } -/* This is for external subtraction of cycles, ie. wait states. */ +/* This is for external subtraction of cycles. */ void sub_cycles(int c) { - if (is286) - cycles -= c; - else { - if (c > 0) - cycles_idle(c); - } + if (c <= 0) + return; + + cycles -= c; + + if (!is286) + fetch_and_bus(c, 2); } void resub_cycles(int old_cycles) { - int i, cyc_diff = 0; + int cyc_diff = 0; if (old_cycles > cycles) { cyc_diff = old_cycles - cycles; - - for (i = 0; i < cyc_diff; i++) { - if (not_ready > 0) - not_ready--; - } + cycles = old_cycles; + sub_cycles(cyc_diff); } - - process_timers(); } #undef readmemb @@ -552,63 +238,53 @@ resub_cycles(int old_cycles) static void cpu_io(int bits, int out, uint16_t port) { -#ifdef REENIGNE_MODELING - bus_init(); -#endif + int old_cycles = cycles; if (out) { + wait(4, 1); if (bits == 16) { if (is8086 && !(port & 1)) { - bus_request_type = BUS_IO | BUS_OUT | BUS_WIDE; - wait(4, 1); + old_cycles = cycles; + outw(port, AX); } else { - bus_request_type = BUS_IO | BUS_OUT; - wait(4, 1); - schedule_fetch = 0; - bus_request_type = BUS_IO | BUS_OUT | BUS_HIGH; wait(4, 1); + old_cycles = cycles; + outb(port++, AL); + outb(port, AH); } } else { - bus_request_type = BUS_IO | BUS_OUT; - wait(4, 1); + old_cycles = cycles; + outb(port, AL); } } else { + wait(4, 1); if (bits == 16) { if (is8086 && !(port & 1)) { - bus_request_type = BUS_IO | BUS_WIDE; - wait(4, 1); + old_cycles = cycles; + AX = inw(port); } else { - bus_request_type = BUS_IO; - wait(4, 1); - schedule_fetch = 0; - bus_request_type = BUS_IO | BUS_HIGH; wait(4, 1); + old_cycles = cycles; + AL = inb(port++); + AH = inb(port); } } else { - bus_request_type = BUS_IO; - wait(4, 1); + old_cycles = cycles; + AL = inb(port); } } - bus_request_type = 0; + resub_cycles(old_cycles); } /* Reads a byte from the memory and advances the BIU. */ static uint8_t -readmemb(uint32_t s, uint16_t a) +readmemb(uint32_t a) { uint8_t ret; -#ifdef REENIGNE_MODELING - bus_init(); -#endif - - mem_seg = s; - mem_addr = a; - bus_request_type = BUS_MEM; wait(4, 1); - ret = mem_data & 0xff; - bus_request_type = 0; + ret = read_mem_b(a); return ret; } @@ -622,8 +298,6 @@ readmembf(uint32_t a) a = cs + (a & 0xffff); ret = read_mem_b(a); - last_was_code = 1; - return ret; } @@ -633,24 +307,14 @@ readmemw(uint32_t s, uint16_t a) { uint16_t ret; -#ifdef REENIGNE_MODELING - bus_init(); -#endif - - mem_seg = s; - mem_addr = a; - if (is8086 && !(a & 1)) { - bus_request_type = BUS_MEM | BUS_WIDE; - wait(4, 1); - } else { - bus_request_type = BUS_MEM | BUS_HIGH; - wait(4, 1); - schedule_fetch = 0; - bus_request_type = BUS_MEM; + wait(4, 1); + if (is8086 && !(a & 1)) + ret = read_mem_w(s + a); + else { wait(4, 1); + ret = read_mem_b(s + a); + ret |= read_mem_b(s + ((is186 && !is_nec) ? (a + 1) : (a + 1) & 0xffff)) << 8; } - ret = mem_data; - bus_request_type = 0; return ret; } @@ -662,8 +326,6 @@ readmemwf(uint16_t a) ret = read_mem_w(cs + (a & 0xffff)); - last_was_code = 1; - return ret; } @@ -673,7 +335,7 @@ readmem(uint32_t s) if (opcode & 1) return readmemw(s, cpu_state.eaaddr); else - return (uint16_t) readmemb(s, cpu_state.eaaddr); + return (uint16_t) readmemb(s + cpu_state.eaaddr); } static uint32_t @@ -695,8 +357,6 @@ readmemq(uint32_t s, uint16_t a) temp = (uint64_t) (readmeml(s, a + 4)) << 32; temp |= readmeml(s, a); - last_was_code = 0; - return temp; } @@ -706,16 +366,8 @@ writememb(uint32_t s, uint32_t a, uint8_t v) { uint32_t addr = s + a; -#ifdef REENIGNE_MODELING - bus_init(); -#endif - - mem_seg = s; - mem_addr = a; - mem_data = v; - bus_request_type = BUS_MEM | BUS_OUT; wait(4, 1); - bus_request_type = 0; + write_mem_b(addr, v); if ((addr >= 0xf0000) && (addr <= 0xfffff)) last_addr = addr & 0xffff; @@ -727,24 +379,15 @@ writememw(uint32_t s, uint32_t a, uint16_t v) { uint32_t addr = s + a; -#ifdef REENIGNE_MODELING - bus_init(); -#endif - - mem_seg = s; - mem_addr = a; - mem_data = v; - if (is8086 && !(a & 1)) { - bus_request_type = BUS_MEM | BUS_OUT | BUS_WIDE; - wait(4, 1); - } else { - bus_request_type = BUS_MEM | BUS_OUT | BUS_HIGH; - wait(4, 1); - schedule_fetch = 0; - bus_request_type = BUS_MEM | BUS_OUT; + wait(4, 1); + if (is8086 && !(a & 1)) + write_mem_w(addr, v); + else { + write_mem_b(addr, v & 0xff); wait(4, 1); + addr = s + ((is186 && !is_nec) ? (a + 1) : ((a + 1) & 0xffff)); + write_mem_b(addr, v >> 8); } - bus_request_type = 0; if ((addr >= 0xf0000) && (addr <= 0xfffff)) last_addr = addr & 0xffff; @@ -777,49 +420,38 @@ static void pfq_write(void) { uint16_t tempw; - /* Byte fetch on odd addres on 8086 to simulate the HL toggle. */ - int fetch_word = is8086 && !(pfq_ip & 1); - if (fetch_word && (pfq_pos < (pfq_size - 1))) { + if (is8086 && (pfq_pos < (pfq_size - 1))) { /* The 8086 fetches 2 bytes at a time, and only if there's at least 2 bytes free in the queue. */ tempw = readmemwf(pfq_ip); *(uint16_t *) &(pfq[pfq_pos]) = tempw; - pfq_ip = (pfq_ip + 2) & 0xffff; + pfq_ip += 2; pfq_pos += 2; - } else if (!fetch_word && (pfq_pos < pfq_size)) { + } 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++; } - - if (pfq_pos >= pfq_size) - pfq_pos = pfq_size; } 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--; - if (pfq_pos < 0) - pfq_pos = 0; cpu_state.pc = (cpu_state.pc + 1) & 0xffff; return temp; } /* Fetches a byte from the prefetch queue, or from memory if the queue has - been drained. - - Cycles: 1 If fetching from the queue; - (4 - (biu_cycles & 3)) If fetching from the bus - fetch into the queue; - 1 If fetching from the bus - delay. */ + been drained. */ static uint8_t pfq_fetchb_common(void) { @@ -829,8 +461,7 @@ pfq_fetchb_common(void) /* Reset prefetch queue internal position. */ pfq_ip = cpu_state.pc; /* Fill the queue. */ - while (pfq_pos == 0) - wait(1, 0); + wait(4 - (biu_cycles & 3), 0); } /* Fetch. */ @@ -838,7 +469,6 @@ pfq_fetchb_common(void) return temp; } -/* The timings are above. */ static uint8_t pfq_fetchb(void) { @@ -874,10 +504,18 @@ pfq_fetch(void) /* Adds bytes to the prefetch queue based on the instruction's cycle count. */ static void -pfq_add(void) +pfq_add(int c, int add) { - if (prefetching && (pfq_pos < pfq_size)) - pfq_write(); + int d; + + if ((c <= 0) || (pfq_pos >= pfq_size)) + return; + + for (d = 0; d < c; d++) { + biu_cycles = (biu_cycles + 1) & 0x03; + if (prefetching && add && (biu_cycles == 0x00)) + pfq_write(); + } } /* Clear the prefetch queue - called on reset and on anything that affects either CS or IP. */ @@ -886,16 +524,6 @@ pfq_clear(void) { pfq_pos = 0; prefetching = 0; - schedule_fetch = 0; - - BUS_CYCLE_T1; -} - -static void -pfq_suspend(void) -{ - pfq_clear(); - cycles_idle(3); } static void @@ -915,7 +543,7 @@ load_seg(uint16_t seg, x86seg *s) void reset_808x(int hard) { - BUS_CYCLE_T1; + biu_cycles = 0; in_rep = 0; in_lock = 0; completed = 1; @@ -945,24 +573,10 @@ reset_808x(int hard) rammask = 0xfffff; prefetching = 1; - - schedule_fetch = 1; - pasv = 0; - cpu_alu_op = 0; use_custom_nmi_vector = 0x00; custom_nmi_vector = 0x00000000; - - access_code = 0; - hlda = 0; - not_ready = 0; - bus_request_type = 0; - pic_data = -1; - last_was_code = 0; - mem_data = 0; - mem_seg = 0; - mem_addr = 0; } static void @@ -970,7 +584,6 @@ set_ip(uint16_t new_ip) { pfq_ip = cpu_state.pc = new_ip; prefetching = 1; - schedule_fetch = prefetching && (pfq_pos < pfq_size); } /* Memory refresh read - called by reads and writes on DMA channel 0. */ @@ -1013,34 +626,34 @@ do_mod_rm(void) if (cpu_mod == 3) return; - wait(2, 0); + wait(1, 0); if ((rmdat & 0xc7) == 0x06) { + wait(1, 0); cpu_state.eaaddr = pfq_fetchw(); easeg = ovr_seg ? *ovr_seg : ds; - wait(2, 0); + wait(1, 0); return; - } else switch (cpu_rm) { - case 0: - case 3: - wait(2, 0); - break; - case 1: - case 2: - wait(3, 0); - break; - } + } else + switch (cpu_rm) { + case 0: + case 3: + wait(2, 0); + break; + case 1: + case 2: + wait(3, 0); + break; + } cpu_state.eaaddr = (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); easeg = ovr_seg ? *ovr_seg : *mod1seg[cpu_rm]; switch (rmdat & 0xc0) { case 0x40: - wait(2, 0); + wait(3, 0); cpu_state.eaaddr += sign_extend(pfq_fetchb()); - wait(1, 0); break; case 0x80: - wait(2, 0); + wait(3, 0); cpu_state.eaaddr += pfq_fetchw(); - wait(1, 0); break; } cpu_state.eaaddr &= 0xffff; @@ -1064,7 +677,7 @@ geteab(void) if (cpu_mod == 3) return (getr8(cpu_rm)); - return readmemb(easeg, cpu_state.eaaddr); + return readmemb(easeg + cpu_state.eaaddr); } /* Reads a word from the effective address. */ @@ -1108,7 +721,7 @@ read_ea(int memory_only, int bits) if (bits == 16) cpu_data = readmemw(easeg, cpu_state.eaaddr); else - cpu_data = readmemb(easeg, cpu_state.eaaddr); + cpu_data = readmemb(easeg + cpu_state.eaaddr); return; } if (!memory_only) { @@ -1126,7 +739,7 @@ read_ea2(int bits) if (bits == 16) cpu_data = readmemw(easeg, cpu_state.eaaddr); else - cpu_data = readmemb(easeg, cpu_state.eaaddr); + cpu_data = readmemb(easeg + cpu_state.eaaddr); } /* Writes a byte to the effective address. */ @@ -1201,6 +814,135 @@ pop(void) return readmemw(ss, cpu_state.eaaddr); } +static void +access(int num, int bits) +{ + switch (num) { + case 0: + case 61: + case 63: + case 64: + case 67: + case 69: + case 71: + case 72: + default: + break; + case 1: + case 6: + case 7: + case 8: + case 9: + case 17: + case 20: + case 21: + case 24: + case 28: + case 47: + case 48: + case 49: + case 50: + case 51: + case 55: + case 56: + case 62: + case 66: + case 68: + wait(1, 0); + break; + case 3: + case 11: + case 15: + case 22: + case 23: + case 25: + case 26: + case 35: + case 44: + case 45: + case 46: + case 52: + case 53: + case 54: + wait(2, 0); + break; + case 16: + case 18: + case 19: + case 27: + case 32: + case 37: + case 42: + wait(3, 0); + break; + case 10: + case 12: + case 13: + case 14: + case 29: + case 30: + case 33: + case 34: + case 39: + case 41: + case 60: + wait(4, 0); + break; + case 4: + case 70: + wait(5, 0); + break; + case 31: + case 38: + case 40: + wait(6, 0); + break; + case 5: + if (opcode == 0xcc) + wait(7, 0); + else + wait(4, 0); + break; + case 36: + wait(1, 0); + pfq_clear(); + wait(1, 0); + if (cpu_mod != 3) + wait(1, 0); + wait(3, 0); + break; + case 43: + wait(2, 0); + pfq_clear(); + wait(1, 0); + break; + case 57: + if (cpu_mod != 3) + wait(2, 0); + wait(4, 0); + break; + case 58: + if (cpu_mod != 3) + wait(1, 0); + wait(4, 0); + break; + case 59: + wait(2, 0); + pfq_clear(); + if (cpu_mod != 3) + wait(1, 0); + wait(3, 0); + break; + case 65: + wait(1, 0); + pfq_clear(); + wait(2, 0); + if (cpu_mod != 3) + wait(1, 0); + break; + } +} + /* Calls an interrupt. */ static void interrupt(uint16_t addr) @@ -1212,24 +954,26 @@ interrupt(uint16_t addr) addr <<= 2; cpu_state.eaaddr = addr; old_cs = CS; + access(5, 16); new_ip = readmemw(0, cpu_state.eaaddr); wait(1, 0); cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; + access(6, 16); new_cs = readmemw(0, cpu_state.eaaddr); prefetching = 0; pfq_clear(); ovr_seg = NULL; - wait(2, 0); + access(39, 16); tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); push(&tempf); cpu_state.flags &= ~(I_FLAG | T_FLAG); - wait(5, 0); + access(40, 16); push(&old_cs); old_ip = cpu_state.pc; load_cs(new_cs); - pfq_suspend(); + access(68, 16); set_ip(new_ip); - wait(2, 0); + access(41, 16); push(&old_ip); } @@ -1248,26 +992,28 @@ custom_nmi(void) cpu_state.eaaddr = 0x0002; old_cs = CS; + access(5, 16); (void) readmemw(0, cpu_state.eaaddr); new_ip = custom_nmi_vector & 0xffff; wait(1, 0); cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; + access(6, 16); (void) readmemw(0, cpu_state.eaaddr); new_cs = custom_nmi_vector >> 16; prefetching = 0; pfq_clear(); ovr_seg = NULL; - wait(2, 0); + access(39, 16); tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); push(&tempf); cpu_state.flags &= ~(I_FLAG | T_FLAG); - wait(5, 0); + access(40, 16); push(&old_cs); old_ip = cpu_state.pc; load_cs(new_cs); - pfq_suspend(); + access(68, 16); set_ip(new_ip); - wait(2, 0); + access(41, 16); push(&old_ip); } @@ -1281,18 +1027,6 @@ irq_pending(void) return temp; } -static int -bus_pic_ack(void) -{ - int old_in_lock = in_lock; - - in_lock = 1; - bus_request_type = BUS_PIC; - wait(4, 1); - in_lock = old_in_lock; - return pic_data; -} - static void check_interrupts(void) { @@ -1300,13 +1034,11 @@ check_interrupts(void) if (irq_pending()) { if ((cpu_state.flags & T_FLAG) && !noint) { - wait(2, 0); interrupt(1); return; } if (nmi && nmi_enable && nmi_mask) { nmi_enable = 0; - wait(2, 0); if (use_custom_nmi_vector) custom_nmi(); else @@ -1320,61 +1052,26 @@ check_interrupts(void) repeating = 0; completed = 1; ovr_seg = NULL; - wait(4, 0); + wait(3, 0); /* ACK to PIC */ - temp = bus_pic_ack(); + temp = pic_irq_ack(); + wait(4, 1); wait(1, 0); /* ACK to PIC */ - temp = bus_pic_ack(); + temp = pic_irq_ack(); + wait(4, 1); wait(1, 0); in_lock = 0; clear_lock = 0; - if (BUS_CYCLE != BUS_T3) - wait(1, 0); - wait(5, 0); + wait(1, 0); /* Here is where temp should be filled, but we cheat. */ + wait(3, 0); opcode = 0x00; interrupt(temp); } } } -static uint16_t tmpc; - -static int -rep_setup(void) -{ - if (repeating) - return 0; - wait(2, 0); - if (in_rep == 0) - return 0; - wait(4, 0); - tmpc = CX; - if (tmpc == 0) - return 1; - wait(3, 0); - return 0; -} - -static int -rep_interrupt(void) -{ - if (!irq_pending()) { - repeating = 1; - completed = 0; - return 0; - } - completed = 1; - CX = tmpc; - pfq_clear(); - if (is_nec && (ovr_seg != NULL)) - set_ip(cpu_state.pc - 3); - else - set_ip(cpu_state.pc - 2); - return 1; -} - static int rep_action(int bits) { @@ -1385,6 +1082,7 @@ rep_action(int bits) wait(2, 0); t = CX; if (irq_pending() && (repeating != 0)) { + access(71, bits); pfq_clear(); if (is_nec && (ovr_seg != NULL)) set_ip(cpu_state.pc - 3); @@ -1410,9 +1108,9 @@ static uint16_t jump(uint16_t delta) { uint16_t old_ip; - wait(1, 0); - pfq_suspend(); - cycles_idle(1); + access(67, 8); + pfq_clear(); + wait(5, 0); old_ip = cpu_state.pc; set_ip((cpu_state.pc + delta) & 0xffff); return old_ip; @@ -1434,6 +1132,8 @@ jump_near(void) static void jcc(uint8_t opcode, int cond) { + /* int8_t offset; */ + wait(1, 0); cpu_data = pfq_fetchb(); wait(1, 0); @@ -1836,7 +1536,7 @@ lods(int bits) if (bits == 16) cpu_data = readmemw((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); else - cpu_data = readmemb((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + cpu_data = readmemb((ovr_seg ? *ovr_seg : ds) + cpu_state.eaaddr); SI = string_increment(bits); } @@ -1958,7 +1658,6 @@ execx86(int cycs) uint16_t tempw_int, size, tempbp, lowbound; uint16_t highbound, regval, orig_sp, wordtopush; uint16_t immediate, old_flags; - uint16_t tmpa; int bits; uint32_t dest_seg, i, carry, nibble; uint32_t srcseg, byteaddr; @@ -1970,8 +1669,7 @@ execx86(int cycs) if (!repeating) { cpu_state.oldpc = cpu_state.pc; - // opcode = pfq_fetchb(); - opcode = pfq_fetchb_common(); + opcode = pfq_fetchb(); handled = 0; oldc = cpu_state.flags & C_FLAG; if (clear_lock) { @@ -1982,7 +1680,7 @@ execx86(int cycs) } completed = 1; - x808x_log("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode); + // pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode); if (is186) { switch (opcode) { case 0x60: /*PUSHA/PUSH R*/ @@ -2122,7 +1820,7 @@ execx86(int cycs) SI += (cpu_state.flags & D_FLAG) ? -2 : 2; } else { wait(4, 0); - outb(DX, readmemb(dest_seg, SI)); + outb(DX, readmemb(dest_seg + SI)); SI += (cpu_state.flags & D_FLAG) ? -1 : 1; } if (in_rep == 0) @@ -2160,6 +1858,7 @@ execx86(int cycs) do_mod_rm(); if (cpu_mod == 3) wait(1, 0); + access(53, bits); cpu_data = get_ea(); cpu_src = pfq_fetchb(); @@ -2238,6 +1937,7 @@ execx86(int cycs) wait(4, 0); --cpu_src; } + access(17, bits); set_ea(cpu_data); handled = 1; break; @@ -2255,7 +1955,7 @@ execx86(int cycs) case 0x0E: case 0x16: case 0x1E: /* PUSH seg */ - wait(3, 0); + access(29, 16); push(&(_opseg[(opcode >> 3) & 0x03]->seg)); break; case 0x07: @@ -2529,7 +2229,7 @@ execx86(int cycs) AX = 0; for (i = 0; i < bit_length; i++) { byteaddr = (ds) + SI; - AX |= (!!(readmemb((ds), SI) & (1 << bit_offset))) << i; + AX |= (!!(readmemb(byteaddr) & (1 << bit_offset))) << i; bit_offset++; if (bit_offset == 8) { SI++; @@ -2548,19 +2248,22 @@ execx86(int cycs) default: opcode = orig_opcode; - cpu_state.pc = (cpu_state.pc - 1) & 0xffff; + cpu_state.pc--; break; } - } else { - wait(1, 0); - if (opcode == 0x0F) { - load_cs(pop()); - pfq_pos = 0; - } else - load_seg(pop(), _opseg[(opcode >> 3) & 0x03]); - /* All POP segment instructions suppress interrupts for one instruction. */ - noint = 1; - } + } else + handled = 0; + if (handled) + break; + access(22, 16); + if (opcode == 0x0F) { + load_cs(pop()); + pfq_pos = 0; + } else + load_seg(pop(), _opseg[(opcode >> 3) & 0x03]); + wait(1, 0); + /* All POP segment instructions suppress interrupts for one instruction. */ + noint = 1; break; case 0x26: /*ES:*/ @@ -2607,6 +2310,7 @@ execx86(int cycs) /* alu rm, r / r, rm */ bits = 8 << (opcode & 1); do_mod_rm(); + access(46, bits); tempw = get_ea(); cpu_alu_op = (opcode >> 3) & 7; if ((opcode & 2) == 0) { @@ -2616,19 +2320,22 @@ execx86(int cycs) cpu_dest = get_reg(cpu_reg); cpu_src = tempw; } - wait(1, 0); if (cpu_mod != 3) - wait(1, 0); - alu_op(bits); + wait(2, 0); wait(1, 0); + alu_op(bits); if (cpu_alu_op != 7) { if ((opcode & 2) == 0) { - if (cpu_mod == 3) - wait(2, 0); + access(10, bits); set_ea(cpu_data); - } else + if (cpu_mod == 3) + wait(1, 0); + } else { set_reg(cpu_reg, cpu_data); - } + wait(1, 0); + } + } else + wait(1, 0); break; case 0x04: @@ -2778,7 +2485,7 @@ execx86(int cycs) case 0x55: case 0x56: case 0x57: - wait(3, 0); + access(30, 16); push(&(cpu_state.regs[opcode & 0x07].w)); break; case 0x58: @@ -2789,8 +2496,9 @@ execx86(int cycs) case 0x5D: case 0x5E: case 0x5F: - wait(1, 0); + access(23, 16); cpu_state.regs[opcode & 0x07].w = pop(); + wait(1, 0); break; case 0x60: /*JO alias*/ @@ -2853,14 +2561,18 @@ execx86(int cycs) /* alu rm, imm */ bits = 8 << (opcode & 1); do_mod_rm(); + access(47, bits); cpu_data = get_ea(); cpu_dest = cpu_data; if (cpu_mod != 3) - wait(1, 0); - wait(1, 0); - if (opcode == 0x81) + wait(3, 0); + if (opcode == 0x81) { + if (cpu_mod == 3) + wait(1, 0); cpu_src = pfq_fetchw(); - else { + } else { + if (cpu_mod == 3) + wait(1, 0); if (opcode == 0x83) cpu_src = sign_extend(pfq_fetchb()); else @@ -2870,8 +2582,7 @@ execx86(int cycs) cpu_alu_op = (rmdat & 0x38) >> 3; alu_op(bits); if (cpu_alu_op != 7) { - if (cpu_mod != 3) - wait(1, 0); + access(11, bits); set_ea(cpu_data); } else { if (cpu_mod != 3) @@ -2884,10 +2595,11 @@ execx86(int cycs) /* TEST rm, reg */ bits = 8 << (opcode & 1); do_mod_rm(); + access(48, bits); cpu_data = get_ea(); test(bits, cpu_data, get_reg(cpu_reg)); - if (cpu_mod != 3) - wait(1, 0); + if (cpu_mod == 3) + wait(2, 0); wait(2, 0); break; case 0x86: @@ -2895,12 +2607,12 @@ execx86(int cycs) /* XCHG rm, reg */ bits = 8 << (opcode & 1); do_mod_rm(); + access(49, bits); cpu_data = get_ea(); cpu_src = get_reg(cpu_reg); set_reg(cpu_reg, cpu_data); wait(3, 0); - if (cpu_mod != 3) - wait(3, 0); + access(12, bits); set_ea(cpu_src); break; @@ -2910,8 +2622,7 @@ execx86(int cycs) bits = 8 << (opcode & 1); do_mod_rm(); wait(1, 0); - if (cpu_mod != 3) - wait(3, 0); + access(13, bits); set_ea(get_reg(cpu_reg)); break; case 0x8A: @@ -2919,17 +2630,18 @@ execx86(int cycs) /* MOV reg, rm */ bits = 8 << (opcode & 1); do_mod_rm(); + access(50, bits); set_reg(cpu_reg, get_ea()); wait(1, 0); if (cpu_mod != 3) - wait(1, 0); + wait(2, 0); break; case 0x8C: /*MOV w,sreg*/ do_mod_rm(); - wait(1, 0); - if (cpu_mod != 3) - wait(2, 0); + if (cpu_mod == 3) + wait(1, 0); + access(14, 16); seteaw(_opseg[(rmdat & 0x18) >> 3]->seg); break; @@ -2938,11 +2650,12 @@ execx86(int cycs) cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; wait(1, 0); if (cpu_mod != 3) - wait(1, 0); + wait(2, 0); break; case 0x8E: /*MOV sreg,w*/ do_mod_rm(); + access(51, 16); tempw = geteaw(); if ((rmdat & 0x18) == 0x08) { load_cs(tempw); @@ -2951,22 +2664,22 @@ execx86(int cycs) load_seg(tempw, _opseg[(rmdat & 0x18) >> 3]); wait(1, 0); if (cpu_mod != 3) - wait(1, 0); + wait(2, 0); if (((rmdat & 0x18) >> 3) == 2) noint = 1; break; case 0x8F: /*POPW*/ do_mod_rm(); - wait(2, 0); - cpu_src = cpu_state.eaaddr; - if (cpu_mod != 3) - wait(1, 0); wait(1, 0); + cpu_src = cpu_state.eaaddr; + access(24, 16); if (cpu_mod != 3) wait(2, 0); cpu_data = pop(); cpu_state.eaaddr = cpu_src; + wait(2, 0); + access(15, 16); seteaw(cpu_data); break; @@ -3004,14 +2717,14 @@ execx86(int cycs) new_ip = pfq_fetchw(); wait(1, 0); new_cs = pfq_fetchw(); - wait(1, 0); - pfq_suspend(); + pfq_clear(); + access(31, 16); push(&(CS)); - wait(4, 0); + access(60, 16); cpu_state.oldpc = cpu_state.pc; load_cs(new_cs); set_ip(new_ip); - wait(1, 0); + access(32, 16); push((uint16_t *) &(cpu_state.oldpc)); break; case 0x9B: /*WAIT*/ @@ -3033,7 +2746,7 @@ execx86(int cycs) #endif break; case 0x9C: /*PUSHF*/ - wait(4, 0); + access(33, 16); if (is_nec) tempw = (cpu_state.flags & 0x8fd7) | 0x7000; else @@ -3041,11 +2754,12 @@ execx86(int cycs) push(&tempw); break; case 0x9D: /*POPF*/ - wait(1, 0); + access(25, 16); if (is_nec) cpu_state.flags = pop() | 0x8002; else cpu_state.flags = pop() | 0x0002; + wait(1, 0); break; case 0x9E: /*SAHF*/ wait(1, 0); @@ -3061,18 +2775,20 @@ execx86(int cycs) case 0xA1: /* MOV A, [iw] */ bits = 8 << (opcode & 1); - wait(2, 0); + wait(1, 0); cpu_state.eaaddr = pfq_fetchw(); + access(1, bits); set_accum(bits, readmem((ovr_seg ? *ovr_seg : ds))); + wait(1, 0); break; case 0xA2: case 0xA3: /* MOV [iw], A */ bits = 8 << (opcode & 1); - wait(2, 0); + wait(1, 0); cpu_state.eaaddr = pfq_fetchw(); + access(7, bits); writemem((ovr_seg ? *ovr_seg : ds), get_accum(bits)); - wait(2, 0); break; case 0xA4: @@ -3080,33 +2796,37 @@ execx86(int cycs) case 0xAC: case 0xAD: /* LODS */ bits = 8 << (opcode & 1); - if (rep_setup()) - break; - if (in_rep != 0 && (BUS_CYCLE == BUS_T4)) + if (!repeating) { wait(1, 0); + if ((opcode & 8) == 0 && in_rep != 0) + wait(1, 0); + } + if (rep_action(bits)) { + wait(1, 0); + if ((opcode & 8) != 0) + wait(1, 0); + break; + } + if (in_rep != 0 && (opcode & 8) != 0) + wait(1, 0); + access(20, bits); lods(bits); if ((opcode & 8) == 0) { - wait(1, 0); + access(27, bits); stos(bits); - } else - set_accum(bits, cpu_data); - wait(3, 0); - if (in_rep == 0) - break; - --tmpc; - if (rep_interrupt()) - break; - CX = tmpc; - if (tmpc == 0) { - completed = 1; - wait(1, 0); - if ((opcode & 8) != 0) - wait(2, 0); } else { - wait(2, 0); - if ((opcode & 8) != 0) + set_accum(bits, cpu_data); + if (in_rep != 0) wait(2, 0); } + if (in_rep == 0) { + wait(3, 0); + if ((opcode & 8) != 0) + wait(1, 0); + break; + } + repeating = 1; + clock_end(); break; case 0xA6: @@ -3114,39 +2834,40 @@ execx86(int cycs) case 0xAE: case 0xAF: /* SCAS */ bits = 8 << (opcode & 1); - if (rep_setup()) - break; - tmpa = AX; - if ((opcode & 8) == 0) { + if (!repeating) wait(1, 0); - lods(bits); - tmpa = cpu_data; - } - wait(2, 0); - cpu_state.eaaddr = DI; - cpu_data = readmem(es); - DI = string_increment(bits); - cpu_src = cpu_data; - cpu_dest = tmpa; - sub(bits); - wait(2, 0); - if (in_rep == 0) { + if (rep_action(bits)) { wait(2, 0); break; } - --tmpc; - CX = tmpc; - if ((!!(cpu_state.flags & (rep_c_flag ? C_FLAG : Z_FLAG))) == (in_rep == 1)) { + if (in_rep != 0) + wait(1, 0); + wait(1, 0); + cpu_dest = get_accum(bits); + if ((opcode & 8) == 0) { + access(21, bits); + lods(bits); + wait(1, 0); + cpu_dest = cpu_data; + } + access(2, bits); + cpu_state.eaaddr = DI; + cpu_data = readmem(es); + DI = string_increment(bits); + cpu_src = cpu_data; + sub(bits); + wait(2, 0); + if (in_rep == 0) { wait(3, 0); break; } - if (rep_interrupt()) - break; - wait(4, 0); - if (tmpc == 0) + if ((!!(cpu_state.flags & (rep_c_flag ? C_FLAG : Z_FLAG))) == (in_rep == 1)) { completed = 1; - else - wait(1, 0); + wait(4, 0); + break; + } + repeating = 1; + clock_end(); break; case 0xA8: @@ -3162,24 +2883,24 @@ execx86(int cycs) case 0xAA: case 0xAB: /* STOS */ bits = 8 << (opcode & 1); - if (rep_setup()) + if (!repeating) { + wait(1, 0); + if (in_rep != 0) + wait(1, 0); + } + if (rep_action(bits)) { + wait(1, 0); break; + } cpu_data = AX; - if (in_rep == 0 && (BUS_CYCLE == BUS_T4)) - wait(1, 0); + access(28, bits); stos(bits); - wait(3, 0); - if (in_rep == 0) + if (in_rep == 0) { + wait(3, 0); break; - --tmpc; - if (rep_interrupt()) - break; - CX = tmpc; - if (tmpc == 0) { - completed = 1; - wait(1, 0); - } else - wait(2, 0); + } + repeating = 1; + clock_end(); break; case 0xB0: @@ -3221,27 +2942,32 @@ execx86(int cycs) case 0xCB: /* RET */ bits = 8 + (opcode & 0x08); - wait(1, 0); + if ((opcode & 9) != 1) + wait(1, 0); if (!(opcode & 1)) { cpu_src = pfq_fetchw(); - wait(2, 0); + wait(1, 0); } if ((opcode & 9) == 9) - wait(2, 0); + wait(1, 0); pfq_clear(); + access(26, bits); new_ip = pop(); - wait(1, 0); - if ((opcode & 8) == 0) { + wait(2, 0); + if ((opcode & 8) == 0) new_cs = CS; + else { + access(42, bits); + new_cs = pop(); if (opcode & 1) wait(1, 0); - } else { - wait(2, 0); - new_cs = pop(); } - if (!(opcode & 1)) + if (!(opcode & 1)) { SP += cpu_src; + wait(1, 0); + } load_cs(new_cs); + access(72, bits); set_ip(new_ip); break; @@ -3250,12 +2976,13 @@ execx86(int cycs) /* LsS rw, rmd */ do_mod_rm(); bits = 16; + access(52, bits); read_ea(1, bits); cpu_state.regs[cpu_reg].w = cpu_data; - if (cpu_mod != 3) - wait(2, 0); + access(57, bits); read_ea2(bits); load_seg(cpu_data, (opcode & 0x01) ? &cpu_state.seg_ds : &cpu_state.seg_es); + wait(1, 0); break; case 0xC6: @@ -3264,40 +2991,40 @@ execx86(int cycs) bits = 8 << (opcode & 1); do_mod_rm(); wait(1, 0); + if (cpu_mod != 3) + wait(2, 0); cpu_data = pfq_fetch(); - wait(2, 0); + if (cpu_mod == 3) + wait(1, 0); + access(16, bits); set_ea(cpu_data); break; case 0xCC: /*INT 3*/ - wait(7, 0); interrupt(3); break; case 0xCD: /*INT*/ wait(1, 0); - temp = pfq_fetchb(); - wait(1, 0); - if (BUS_CYCLE != BUS_T4) - wait(1, 0); - wait(1, 0); - - interrupt(temp); + interrupt(pfq_fetchb()); break; case 0xCE: /*INTO*/ wait(3, 0); if (cpu_state.flags & V_FLAG) { - wait(5, 0); + wait(2, 0); interrupt(4); } break; case 0xCF: /*IRET*/ - wait(3, 0); - pfq_clear(); + access(43, 8); new_ip = pop(); + wait(3, 0); + access(44, 8); new_cs = pop(); load_cs(new_cs); + access(62, 8); set_ip(new_ip); + access(45, 8); if (is_nec) cpu_state.flags = pop() | 0x8002; else @@ -3314,9 +3041,10 @@ execx86(int cycs) /* rot rm */ bits = 8 << (opcode & 1); do_mod_rm(); - cpu_data = get_ea(); if (cpu_mod == 3) wait(1, 0); + access(53, bits); + cpu_data = get_ea(); if ((opcode & 2) == 0) { cpu_src = 1; wait((cpu_mod != 3) ? 4 : 0, 0); @@ -3397,16 +3125,21 @@ execx86(int cycs) wait(4, 0); --cpu_src; } + access(17, bits); set_ea(cpu_data); break; 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; @@ -3430,8 +3163,9 @@ execx86(int cycs) break; case 0xD7: /*XLATB*/ cpu_state.eaaddr = (BX + AL) & 0xffff; - wait(4, 0); - AL = readmemb((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + access(4, 8); + AL = readmemb((ovr_seg ? *ovr_seg : ds) + cpu_state.eaaddr); + wait(1, 0); break; case 0xD8: @@ -3444,70 +3178,42 @@ execx86(int cycs) case 0xDF: /* esc i, r, rm */ do_mod_rm(); + access(54, 16); tempw = cpu_state.pc; - geteaw(); - wait(1, 0); - if (cpu_mod != 3) - wait(1, 0); - if (hasfpu) { - 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; - } + if (!hasfpu) + geteaw(); + 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); + if (cpu_mod != 3) + wait(2, 0); break; case 0xE0: @@ -3540,46 +3246,43 @@ execx86(int cycs) case 0xE4: case 0xE5: - bits = 8 << (opcode & 1); - wait(1, 0); - cpu_data = pfq_fetchb(); - cpu_state.eaaddr = cpu_data; - wait(1, 0); - cpu_io(bits, 0, cpu_state.eaaddr); - break; case 0xE6: case 0xE7: - bits = 8 << (opcode & 1); - wait(1, 0); - cpu_data = pfq_fetchb(); - cpu_state.eaaddr = cpu_data; - cpu_data = (bits == 16) ? AX : AL; - wait(2, 0); - cpu_io(bits, 1, cpu_state.eaaddr); - break; case 0xEC: case 0xED: - bits = 8 << (opcode & 1); - cpu_data = DX; - cpu_state.eaaddr = cpu_data; - wait(1, 0); - cpu_io(bits, 0, cpu_state.eaaddr); - break; case 0xEE: case 0xEF: bits = 8 << (opcode & 1); - wait(2, 0); - cpu_data = DX; + if ((opcode & 0x0e) != 0x0c) + wait(1, 0); + if ((opcode & 8) == 0) + cpu_data = pfq_fetchb(); + else + cpu_data = DX; cpu_state.eaaddr = cpu_data; - cpu_data = (bits == 16) ? AX : AL; - cpu_io(bits, 1, cpu_state.eaaddr); - wait(1, 0); + if ((opcode & 2) == 0) { + access(3, bits); + if (opcode & 1) + cpu_io(16, 0, cpu_data); + else + cpu_io(8, 0, cpu_data); + wait(1, 0); + } else { + if ((opcode & 8) == 0) + access(8, bits); + else + access(9, bits); + if (opcode & 1) + cpu_io(16, 1, cpu_data); + else + cpu_io(8, 1, cpu_data); + } break; case 0xE8: /*CALL rel 16*/ wait(1, 0); cpu_state.oldpc = jump_near(); - wait(2, 0); + access(34, 8); push((uint16_t *) &(cpu_state.oldpc)); break; case 0xE9: /*JMP rel 16*/ @@ -3592,8 +3295,8 @@ execx86(int cycs) wait(1, 0); tempw = pfq_fetchw(); load_cs(tempw); + access(70, 8); pfq_clear(); - wait(4, 0); set_ip(addr); break; case 0xEB: /*JMP rel*/ @@ -3620,22 +3323,17 @@ execx86(int cycs) case 0xF4: /*HLT*/ if (!repeating) { - if ((BUS_CYCLE == BUS_T4) || !last_was_code) - cpu_data = 1; - else - cpu_data = 2; - wait(2, 0); + wait(1, 0); pfq_clear(); } wait(1, 0); if (irq_pending()) { - wait(1, 0); - if (cpu_data == 2) - wait(1, 0); + wait(cycles & 1, 0); check_interrupts(); } else { repeating = 1; completed = 0; + clock_end(); } break; case 0xF5: /*CMC*/ @@ -3647,12 +3345,15 @@ execx86(int cycs) case 0xF7: bits = 8 << (opcode & 1); do_mod_rm(); + access(55, bits); cpu_data = get_ea(); switch (rmdat & 0x38) { case 0x00: case 0x08: /* TEST */ wait(2, 0); + if (cpu_mod != 3) + wait(1, 0); cpu_src = pfq_fetch(); wait(1, 0); test(bits, cpu_data, cpu_src); @@ -3669,8 +3370,7 @@ execx86(int cycs) cpu_dest = 0; sub(bits); } - if (cpu_mod != 3) - wait(2, 0); + access(18, bits); set_ea(cpu_data); break; case 0x20: /* MUL */ @@ -3692,6 +3392,8 @@ execx86(int cycs) } set_sf(bits); set_pf(); + if (cpu_mod != 3) + wait(1, 0); /* NOTE: When implementing the V20, care should be taken to not change the zero flag. */ if (is_nec) @@ -3699,6 +3401,8 @@ execx86(int cycs) break; case 0x30: /* DIV */ case 0x38: /* IDIV */ + if (cpu_mod != 3) + wait(1, 0); cpu_src = cpu_data; if (x86_div(AL, AH)) wait(1, 0); @@ -3730,6 +3434,7 @@ execx86(int cycs) /* misc */ bits = 8 << (opcode & 1); do_mod_rm(); + access(56, bits); read_ea(((rmdat & 0x38) == 0x18) || ((rmdat & 0x38) == 0x28), bits); switch (rmdat & 0x38) { case 0x00: /* INC rm */ @@ -3746,60 +3451,62 @@ execx86(int cycs) do_af(); set_pzs(bits); wait(2, 0); + access(19, bits); set_ea(cpu_data); break; case 0x10: /* CALL rm */ cpu_data_opff_rm(); - wait(2, 0); + access(63, bits); + wait(1, 0); pfq_clear(); - wait(5, 0); + wait(4, 0); + if (cpu_mod != 3) + wait(1, 0); + wait(1, 0); /* Wait. */ cpu_state.oldpc = cpu_state.pc; set_ip(cpu_data); wait(2, 0); + access(35, bits); push((uint16_t *) &(cpu_state.oldpc)); break; case 0x18: /* CALL rmd */ new_ip = cpu_data; - wait(3, 0); + access(58, bits); read_ea2(bits); if (!(opcode & 1)) cpu_data |= 0xff00; new_cs = cpu_data; - wait(1, 0); - pfq_clear(); + access(36, bits); push(&(CS)); + access(64, bits); wait(4, 0); cpu_state.oldpc = cpu_state.pc; load_cs(new_cs); set_ip(new_ip); - wait(1, 0); + access(37, bits); push((uint16_t *) &(cpu_state.oldpc)); break; case 0x20: /* JMP rm */ cpu_data_opff_rm(); - wait(2, 0); - pfq_clear(); - if (BUS_CYCLE != BUS_T4) - wait(1, 0); + access(65, bits); set_ip(cpu_data); break; case 0x28: /* JMP rmd */ new_ip = cpu_data; - wait(3, 0); - pfq_clear(); - wait(1, 0); + access(59, bits); read_ea2(bits); if (!(opcode & 1)) cpu_data |= 0xff00; new_cs = cpu_data; load_cs(new_cs); + access(66, bits); set_ip(new_ip); break; case 0x30: /* PUSH rm */ case 0x38: if (cpu_mod != 3) wait(1, 0); - wait(4, 0); + access(38, bits); push((uint16_t *) &(cpu_data)); break; } diff --git a/src/cpu/808x/CMakeLists.txt b/src/cpu/808x/CMakeLists.txt deleted file mode 100644 index d29bdf4e0..000000000 --- a/src/cpu/808x/CMakeLists.txt +++ /dev/null @@ -1,16 +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(808x OBJECT queue.c) diff --git a/src/cpu/808x/queue.c b/src/cpu/808x/queue.c deleted file mode 100644 index 2eebde0ce..000000000 --- a/src/cpu/808x/queue.c +++ /dev/null @@ -1,190 +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. - * - * 808x CPU emulation, mostly ported from reenigne's XTCE, which - * is cycle-accurate. - * - * Authors: gloriouscow, - * Miran Grca, - * - * Copyright 2023 gloriouscow. - * Copyright 2023 Miran Grca. - */ -#include -#include -#include -#include -#include -#include - -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include "x86.h" -#include <86box/machine.h> -#include <86box/io.h> -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/nmi.h> -#include <86box/pic.h> -#include <86box/ppi.h> -#include <86box/timer.h> -#include <86box/gdbstub.h> -// #include "808x.h" -#include "queue.h" - -/* TODO: Move to cpu.h so this can eventually be reused for 286+ as well. */ -#define QUEUE_MAX 6 - -typedef struct queue_t -{ - size_t size; - size_t len; - size_t back; - size_t front; - uint8_t q[QUEUE_MAX]; - uint16_t preload; - queue_delay_t delay; -} queue_t; - -static queue_t queue; - -#ifdef ENABLE_QUEUE_LOG -int queue_do_log = ENABLE_QUEUE_LOG; - -static void -queue_log(const char *fmt, ...) -{ - va_list ap; - - if (queue_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define queue_log(fmt, ...) -#endif - -void -queue_set_size(size_t size) -{ - if (size > QUEUE_MAX) - fatal("Requested prefetch queue of %i bytes is too big\n", size); - - queue.size = size; -} - -size_t -queue_get_len(void) -{ - return queue.len; -} - -int -queue_is_full(void) -{ - return (queue.len != queue.size); -} - -uint16_t -queue_get_preload(void) -{ - uint16_t ret = queue.preload; - queue.preload = 0x0000; - - return ret; -} - -int -queue_has_preload(void) -{ - return (queue.preload & FLAG_PRELOADED) ? 1 : 0; -} - -void -queue_set_preload(void) -{ - uint8_t byte; - - if (queue.len > 0) { - byte = queue_pop(); - queue.preload = ((uint16_t) byte) | FLAG_PRELOADED; - } else - fatal("Tried to preload with empty queue\n"); -} - -void -queue_push8(uint8_t byte) -{ - if (queue.len < queue.size) { - queue.q[queue.front] = byte; - queue.front = (queue.front + 1) % queue.size; - queue.len++; - - if (queue.len == 3) - queue.delay = DELAY_WRITE; - else - queue.delay = DELAY_NONE; - } else - fatal("Queue overrun\n"); -} - -void -queue_push16(uint16_t word) -{ - queue_push8((uint8_t) (word & 0xff)); - queue_push8((uint8_t) ((word >> 8) & 0xff)); -} - -uint8_t -queue_pop(void) -{ - uint8_t byte = 0xff; - - if (queue.len > 0) { - byte = queue.q[queue.back]; - - queue.back = (queue.back + 1) % queue.size; - queue.len--; - - if (queue.len >= 3) - queue.delay = DELAY_READ; - else - queue.delay = DELAY_NONE; - } else - fatal("Queue underrun\n"); - - return byte; -} - -queue_delay_t -queue_get_delay(void) -{ - return queue.delay; -} - -void -queue_flush(void) -{ - memset(&queue, 0x00, sizeof(queue_t)); - - queue.delay = DELAY_NONE; -} - -void -queue_init(void) -{ - queue_flush(); - - if (is8086) - queue_set_size(6); - else - queue_set_size(4); -} diff --git a/src/cpu/808x/queue.h b/src/cpu/808x/queue.h deleted file mode 100644 index 544455784..000000000 --- a/src/cpu/808x/queue.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. - * - * Prefetch queue implementation header. - * - * Authors: gloriouscow, - * Miran Grca, - * - * Copyright 2023 gloriouscow. - * Copyright 2023 Miran Grca. - */ -#ifndef EMU_QUEUE_H -#define EMU_QUEUE_H - -typedef enum queue_delay_t -{ - DELAY_READ, - DELAY_WRITE, - DELAY_NONE -} queue_delay_t; - -#define FLAG_PRELOADED 0x8000 - -extern void queue_set_size(size_t size); -extern size_t queue_get_len(void); -extern int queue_is_full(void); -extern uint16_t queue_get_preload(void); -extern int queue_has_preload(void); -extern void queue_set_preload(void); -extern void queue_push8(uint8_t byte); -extern void queue_push16(uint16_t word); -extern uint8_t queue_pop(void); -extern queue_delay_t queue_get_delay(void); -extern void queue_flush(void); - -extern void queue_init(void); - -#endif /*EMU_QUEUE_H*/ diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index e4d8e71b2..bd03a5558 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 x86_ops_mmx.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) @@ -35,6 +36,3 @@ endif() add_subdirectory(softfloat) target_link_libraries(86Box softfloat) - -add_subdirectory(808x) -target_link_libraries(86Box 808x) diff --git a/src/cpu/codegen_public.h b/src/cpu/codegen_public.h index 36393296e..cb7ec57a7 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 2fe5ce417..e862b123e 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) +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; + 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) +void +codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) { - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); + 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; + 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; + 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; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + 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; + 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; - 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); + 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 7d7f4042d..a6800c5b2 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; + 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; + 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); + 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; + 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; + 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; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + 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; + /*One prefix per instruction is free*/ + decode_delay--; + if (decode_delay < 0) + decode_delay = 0; - 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; + if (prev_full) { + uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32); + int agi_stall = 0; - 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; + if (regmask & IMPL_ESP) + regmask |= SRCDEP_ESP | DSTDEP_ESP; - 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; + agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32); - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } + /*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; } + } - /*One prefix per instruction is free*/ - decode_delay--; - if (decode_delay < 0) - decode_delay = 0; + 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; - if (prev_full) - { - uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32); - int agi_stall = 0; + agi_stall = check_agi(deps, opcode, fetchdat, op_32); - 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; - } + 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 a1f1b6ce7..0c538fc4e 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 679997802..3d28a89de 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 6a59fc157..4a9f23cd8 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 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 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_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 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 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 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 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 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 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 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 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 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 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 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 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 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_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 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_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_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 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 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_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_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_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 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 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 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_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_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 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_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_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_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 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 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 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_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 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 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 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 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_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 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 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 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 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) +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; + 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; + /*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; + /*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; + } } + } + if (!best_unit) + fatal("uop_run: can not find execution unit\n"); - /*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 (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; + } - 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; + 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; + start_timestamp = decode_buffer.earliest_start[c]; - /*Advance to next opquad in buffer*/ - opquad_completion_timestamp[next_opquad] = last_complete_timestamp; - next_opquad++; - if (next_opquad == NR_OPQUADS) - next_opquad = 0; + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } - decode_timestamp++; - decode_buffer.nr_uops = 0; + /*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; } /*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) +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; + 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; - } + 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) +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); + 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]; - } + /*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 ((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]; - } + 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; + /*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(); + 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; } - 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; + decode_buffer.nr_uops += ins->nr_uops; - 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_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(); - } + } 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; } - if (d) - { - decode_buffer.nr_uops = d; - decode_flush(); - } - break; - } + } + 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) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps & FPU_WRITE_ST0)) && - !(reg == 1 && (deps & FPU_WRITE_ST1))) - fpu_st_timestamp[reg] = last_complete_timestamp; - } -} + case DECODE_LONG: + if (decode_buffer.nr_uops) + decode_flush(); -void codegen_timing_k6_block_start(void) -{ - int c; - - 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; - - 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_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_prefix(uint8_t prefix, uint32_t fetchdat) -{ - if (prefix != 0x0f) - decode_timestamp++; - - 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; - } - } - - opcode = fastreadb(cs + opcode_pc); - - ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f; - deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; - } + 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 - { - ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - } - break; + decode_buffer.earliest_start[c] = -1; + } + decode_flush(); + 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; + 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; + } + 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; + } +} + +void +codegen_timing_k6_block_start(void) +{ + int c; + + 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; + + 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_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_prefix(uint8_t prefix, uint32_t fetchdat) +{ + if (prefix != 0x0f) + decode_timestamp++; + + 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; + 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; + } + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } + } + + 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; 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; + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + 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; + 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); +} - 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(&vector_alu1_op, 0, fetchdat, op_32, bit8); +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); + } } -void codegen_timing_k6_block_end(void) +int +codegen_timing_k6_jump_cycles(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) + return 1; + return 0; } -int codegen_timing_k6_jump_cycles(void) -{ - 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 cf40e084e..2c087ae86 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 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 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_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 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 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 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 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 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 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 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 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 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 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 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 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 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_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 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_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_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 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 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_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_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_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 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 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_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_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 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_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_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 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 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 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_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 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 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 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 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 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 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_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_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 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 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 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_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 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 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 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 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_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 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 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 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 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 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 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 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 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_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 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 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 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 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 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 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 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 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_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 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 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 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_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 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_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 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 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 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 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 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 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 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 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 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 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 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_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_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 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_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 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_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 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 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 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 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 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 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 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 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 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 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 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_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 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_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 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 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 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 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; + 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; + /*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; - } - } + /*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_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; + 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; + int start_timestamp; + int 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]; + /*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; + /*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]; - - 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; + /*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 - last_complete_timestamp = uop_timestamp; + start_timestamp = decode_buffer.earliest_start[c]; - /*Advance to next opseq in buffer*/ - opseq_completion_timestamp[next_opseq] = last_complete_timestamp; - next_opseq++; - if (next_opseq == NR_OPSEQS) - next_opseq = 0; + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } - decode_timestamp++; - decode_buffer.nr_uops = 0; + /*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; } /*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) +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; + 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; - } + 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) +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); + 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]; - } + /*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 ((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]; - } + 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; + /*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*/ - } - } + 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; + 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*/ } - break; - } + } + 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; - } + /*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) +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; + 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) +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; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int old_last_complete_timestamp = last_complete_timestamp; - int bit8 = !(opcode & 1); + 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; + 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; + 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; + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + 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; + 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); +} - 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); +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); + } } -void codegen_timing_p6_block_end(void) +int +codegen_timing_p6_jump_cycles(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) + return 1; + return 0; } -int codegen_timing_p6_jump_cycles(void) -{ - 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 232455f6d..3951acc94 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_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_COMP_TIME(timing) (timing & 0xff) +#define FPU_I_OVERLAP(timing) ((timing >> 41) & 0xff) +#define FPU_F_OVERLAP(timing) ((timing >> 49) & 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 >> 41) & 0xff) +#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: + 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) +{ + 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]; + + 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); +} + +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; - 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; -} - -static int codegen_fpu_latencies(uint64_t deps, int reg) -{ - 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]; - - 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); -} - -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; - } - 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; + 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; - } + 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; + 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 (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; - } + 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; + 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; + 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) - { - 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] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) - { - 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))) - { - 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))) { + fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); } + } } -void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +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; + 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; + 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; + 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; 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; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + 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; + if (u_pipe_full) { + uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - 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; + if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && (timings[opcode] & PAIR_MASK) != PAIR_FXCH) + goto nopair; - 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; + if ((timings[opcode] & PAIR_MASK) == PAIR_FXCH && (u_pipe_timings[u_pipe_opcode] & PAIR_MASK) != PAIR_FX) + goto nopair; - default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; - break; - } - } + if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && (timings[opcode] & PAIR_MASK) == PAIR_FXCH) { + int 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; - } - - 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)) + 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); - addr_regmask = 0; -} -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; + 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; + } + + 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; } -codegen_timing_t codegen_timing_pentium = +void +codegen_timing_pentium_block_end(void) { - codegen_timing_pentium_start, - codegen_timing_pentium_prefix, - codegen_timing_pentium_opcode, - codegen_timing_pentium_block_start, - codegen_timing_pentium_block_end, - NULL + 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 }; diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c index a1ee02b63..11dd912b4 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) +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; + 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) +void +codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) { - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); + 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; + 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; + 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; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + 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; + 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; - 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); + 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 f96304072..d4e32611e 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) +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; + /*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; + return 1; } -static inline int COUNT(uint32_t c, int op_32) +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); + 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 +#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 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) +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; + 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 ((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 ((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) +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; + 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; + 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; + 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; + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + 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; + if (u_pipe_full) { + uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - 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; + 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; - 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; - } - - if (check_agi(deps, opcode, fetchdat, op_32)) + 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(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) -{ - 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_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; + } + + 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); } -codegen_timing_t codegen_timing_winchip2 = +static void +codegen_timing_winchip2_block_end(void) { - codegen_timing_winchip2_start, - codegen_timing_winchip2_prefix, - codegen_timing_winchip2_opcode, - codegen_timing_winchip2_block_start, - codegen_timing_winchip2_block_end, - NULL + 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 }; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index d633b9bb2..df6684baf 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 @@ -125,6 +130,27 @@ 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 }; @@ -155,6 +181,7 @@ int cpu_multi; int cpu_16bitbus; int cpu_64bitbus; int cpu_cyrix_alignment; +int cpu_cpurst_on_sr; int CPUID; int is186; @@ -216,7 +243,7 @@ uint32_t cache_index = 0; uint8_t _cache[2048]; uint64_t cpu_CR4_mask; -uint64_t tsc = 0; +uint64_t tsc = 0; uint64_t pmc[2] = { 0, 0 }; double cpu_dmulti; @@ -229,10 +256,10 @@ cyrix_t cyrix; cpu_family_t *cpu_f; CPU *cpu_s; -uint8_t do_translate = 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; static uint8_t ccr1; @@ -449,7 +476,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); } } @@ -535,9 +562,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; @@ -599,6 +629,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; @@ -616,6 +663,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 @@ -652,6 +716,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 @@ -662,6 +743,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) { @@ -678,6 +760,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: @@ -686,6 +769,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 @@ -736,6 +820,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; @@ -751,6 +850,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; } } @@ -793,11 +907,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; @@ -846,6 +962,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; @@ -861,6 +992,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; } } @@ -907,6 +1053,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 */ @@ -946,6 +1093,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 */ @@ -984,7 +1132,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: @@ -998,6 +1146,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 */ @@ -1242,7 +1391,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); @@ -1296,7 +1444,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); @@ -1304,7 +1454,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 */ @@ -1352,7 +1504,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; @@ -1447,7 +1598,6 @@ 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) { @@ -1550,7 +1700,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; @@ -1598,8 +1747,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; @@ -1609,7 +1758,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) { @@ -1641,9 +1790,13 @@ cpu_set(void) cpu_exec = exec386_dynarec; 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; + 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(); @@ -1661,12 +1814,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); } @@ -1765,7 +1919,10 @@ cpu_CPUID(void) 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 @@ -2215,9 +2372,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; @@ -2233,9 +2395,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; @@ -2251,9 +2418,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; @@ -2278,6 +2458,8 @@ cpu_CPUID(void) 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; @@ -2287,6 +2469,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 */ @@ -2313,12 +2497,19 @@ 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); + if (cpu_s->cpu_type == CPU_WINCHIP2) + msr.fcr |= (1 << 18) | (1 << 20); + 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: @@ -2332,7 +2523,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; } } @@ -2735,6 +2930,10 @@ amd_k_invalid_rdmsr: EAX = msr.ecx187 & 0xffffffff; EDX = msr.ecx187 >> 32; break; + case 0x1d9: + EAX = msr.debug_ctl & 0xffffffff; + EDX = msr.debug_ctl >> 32; + break; case 0x1e0: EAX = msr.ecx1e0 & 0xffffffff; EDX = msr.ecx1e0 >> 32; @@ -2821,6 +3020,10 @@ amd_k_invalid_rdmsr: EAX = msr.ecx1002ff & 0xffffffff; EDX = msr.ecx1002ff >> 32; break; + case 0x40000020: + EAX = msr.ecx40000020 & 0xffffffff; + EDX = msr.ecx40000020 >> 32; + break; case 0xf0f00250: EAX = msr.ecxf0f00250 & 0xffffffff; EDX = msr.ecxf0f00250 >> 32; @@ -2928,6 +3131,10 @@ cpu_WRMSR(void) 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; case 0x1108: msr.fcr2 = EAX | ((uint64_t) EDX << 32); @@ -3101,7 +3308,9 @@ amd_k_invalid_wrmsr: break; 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; case 0x2a: break; @@ -3172,6 +3381,9 @@ amd_k_invalid_wrmsr: case 0x187: msr.ecx187 = EAX | ((uint64_t) EDX << 32); break; + case 0x1d9: + msr.debug_ctl = EAX | ((uint64_t) EDX << 32); + break; case 0x1e0: msr.ecx1e0 = EAX | ((uint64_t) EDX << 32); break; @@ -3247,6 +3459,9 @@ amd_k_invalid_wrmsr: case 0x1002ff: msr.ecx1002ff = EAX | ((uint64_t) EDX << 32); break; + case 0x40000020: + msr.ecx40000020 = EAX | ((uint64_t) EDX << 32); + break; case 0xf0f00250: msr.ecxf0f00250 = EAX | ((uint64_t) EDX << 32); break; @@ -3267,7 +3482,7 @@ i686_invalid_wrmsr: } 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. */ @@ -3349,7 +3564,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; @@ -3405,11 +3620,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 d13201608..9aee59e60 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -143,7 +143,7 @@ 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; @@ -166,9 +166,9 @@ typedef struct { } cpu_family_t; typedef struct { - const char *family; - const int rspeed; - const double multi; + const char *family; + const uint32_t rspeed; + const double multi; } cpu_legacy_table_t; typedef struct { @@ -280,11 +280,12 @@ typedef struct { /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ + uint64_t ecx186; /* 0x00000186, 0x00000187 */ + uint64_t ecx187; /* 0x00000186, 0x00000187 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx186; /* 0x00000186, 0x00000187 */ - uint64_t ecx187; /* 0x00000186, 0x00000187 */ - uint64_t ecx1e0; /* 0x000001e0 */ + uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */ + uint64_t ecx1e0; /* 0x000001e0 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also on the VIA Cyrix III */ @@ -338,6 +339,9 @@ typedef struct { /* K6-3, K6-2P, and K6-3P MSR's */ uint64_t amd_l2aar; /* 0xc0000089 */ + /* Weird long MSR's used by the Hyper-V BIOS. */ + uint64_t ecx40000020; /* 0x40000020 */ + /* 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 */ @@ -393,8 +397,13 @@ typedef struct { MMX_REG MM[8]; #ifdef USE_NEW_DYNAREC +# 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; uint16_t new_fp_control2; @@ -426,15 +435,15 @@ typedef struct { } 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; unsigned char align2; @@ -444,7 +453,7 @@ typedef struct { #define in_smm cpu_state._in_smm #define smi_line cpu_state._smi_line -#define smbase cpu_state._smbase +#define smbase cpu_state._smbase /*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block to be valid*/ @@ -454,9 +463,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. @@ -538,8 +547,9 @@ 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 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; @@ -584,7 +594,6 @@ 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; @@ -615,8 +624,8 @@ extern uint64_t star; #define FPU_CW_Reserved_Bits (0xe0c0) -#define cr0 cpu_state.CR0.l -#define msw cpu_state.CR0.w +#define cr0 cpu_state.CR0.l +#define msw cpu_state.CR0.w extern uint32_t cr2; extern uint32_t cr3; extern uint32_t cr4; @@ -715,15 +724,6 @@ 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); @@ -743,26 +743,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); @@ -772,11 +760,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); @@ -830,10 +813,12 @@ extern int hlt_reset_pending; extern cyrix_t cyrix; +extern int prefetch_prefixes; + extern uint8_t use_custom_nmi_vector; extern uint32_t custom_nmi_vector; -extern void (*cpu_exec)(int cycs); +extern void (*cpu_exec)(int32_t cycs); extern uint8_t do_translate; extern uint8_t do_translate2; @@ -850,9 +835,12 @@ extern void cpu_fast_off_reset(void); extern void smi_raise(void); extern void nmi_raise(void); -extern MMX_REG *MMP[8]; +extern MMX_REG *MMP[8]; extern uint16_t *MMEP[8]; 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); #endif /*EMU_CPU_H*/ diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 3afaf055e..947804014 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, @@ -378,7 +1196,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 +1227,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 +1248,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 +1257,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} } }, { @@ -1946,6 +2764,7 @@ const cpu_legacy_machine_t cpu_legacy_table[] = { { "award286", cputables_286 }, { "gw286ct", cputables_286 }, { "gdc212m", cputables_286 }, + { "super286c", cputables_286 }, { "super286tr", cputables_286 }, { "spc4200p", cputables_286 }, { "spc4216p", cputables_286 }, diff --git a/src/cpu/softfloat/config.h b/src/cpu/softfloat/config.h index 3889b5c02..9e39c2d29 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 76101c344..64ff6be4c 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,10 @@ 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; #ifdef ENABLE_X86_LOG void dumpregs(int); @@ -80,7 +87,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 +108,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 +180,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 +194,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 +214,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 +231,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) { @@ -264,10 +276,13 @@ reset_common(int hard) cpu_state.eflags = 0; cgate32 = 0; 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 +342,8 @@ reset_common(int hard) if (!is286) reset_808x(hard); + + cpu_cpurst_on_sr = 0; } /* Hard reset. */ @@ -345,7 +362,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 337619fa4..f52e430ac 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 0cd449236..6fb9b7a22 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 ff657d708..b72cbc06c 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -35,7 +35,7 @@ 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(); @@ -56,7 +56,7 @@ opPAVGUSB(uint32_t fetchdat) static int opPF2ID(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -71,7 +71,7 @@ opPF2ID(uint32_t fetchdat) static int opPF2IW(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -86,9 +86,9 @@ opPF2IW(uint32_t fetchdat) static int opPFACC(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); - float tempf; + float tempf; MMX_GETSRC(); @@ -103,9 +103,9 @@ opPFACC(uint32_t fetchdat) static int opPFNACC(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); - float tempf; + float tempf; MMX_GETSRC(); @@ -120,9 +120,9 @@ opPFNACC(uint32_t fetchdat) static int opPFPNACC(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); - float tempf; + float tempf; MMX_GETSRC(); @@ -137,9 +137,10 @@ opPFPNACC(uint32_t fetchdat) static int opPSWAPD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); - float tempf, tempf2; + float tempf; + float tempf2; MMX_GETSRC(); @@ -156,7 +157,7 @@ opPSWAPD(uint32_t fetchdat) static int opPFADD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -171,7 +172,7 @@ opPFADD(uint32_t fetchdat) static int opPFCMPEQ(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -186,7 +187,7 @@ opPFCMPEQ(uint32_t fetchdat) static int opPFCMPGE(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -201,7 +202,7 @@ opPFCMPGE(uint32_t fetchdat) static int opPFCMPGT(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -216,7 +217,7 @@ opPFCMPGT(uint32_t fetchdat) static int opPFMAX(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -233,7 +234,7 @@ opPFMAX(uint32_t fetchdat) static int opPFMIN(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -250,7 +251,7 @@ opPFMIN(uint32_t fetchdat) static int opPFMUL(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -294,7 +295,7 @@ 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(); @@ -309,7 +310,7 @@ opPFRCPIT1(uint32_t fetchdat) static int opPFRCPIT2(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -363,7 +364,7 @@ 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(); @@ -378,7 +379,7 @@ opPFSUB(uint32_t fetchdat) static int opPFSUBR(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -393,7 +394,7 @@ opPFSUBR(uint32_t fetchdat) static int opPI2FD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -408,7 +409,7 @@ opPI2FD(uint32_t fetchdat) static int opPI2FW(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -423,7 +424,7 @@ opPI2FW(uint32_t fetchdat) static int opPMULHRW(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { diff --git a/src/cpu/x86_ops_arith.h b/src/cpu/x86_ops_arith.h index 41c655d09..4e3f74e36 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 7c7b409d2..43a3708e0 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 d3ff97ead..b4779ab3e 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 8514e8e1c..b72142b5a 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 88899cef8..9d52a2764 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_fpu.h b/src/cpu/x86_ops_fpu.h index 29e999941..849e24e3d 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_i686.h b/src/cpu/x86_ops_i686.h index f2b07a1c4..ab9d02d25 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -46,10 +46,10 @@ opSYSEXIT(uint32_t fetchdat) static int sf_fx_save_stor_common(uint32_t fetchdat, int bits) { - uint8_t fxinst = 0; - uint32_t tag_byte; - unsigned index; - floatx80 reg; + uint8_t fxinst = 0; + uint32_t tag_byte; + unsigned index; + floatx80 reg; if (CPUID < 0x650) return ILLEGAL(fetchdat); @@ -129,33 +129,33 @@ sf_fx_save_stor_common(uint32_t fetchdat, int 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 - */ + /* + * 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 - */ + /* + * 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 */ + /* store i387 register file */ for (index = 0; index < 8; index++) { const floatx80 fp = FPU_read_regi(index); @@ -172,70 +172,72 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits) 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); @@ -285,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; @@ -379,7 +381,7 @@ fx_save_stor_common(uint32_t fetchdat, int bits) static int opFXSAVESTOR_a16(uint32_t fetchdat) { - if (fpu_softfloat) + if (fpu_softfloat) return sf_fx_save_stor_common(fetchdat, 16); return fx_save_stor_common(fetchdat, 16); diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index a1503a75e..97ca673d7 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 60ed873e4..e36fa4800 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -55,7 +55,8 @@ opF6_a16(uint32_t fetchdat) int tempws2 = 0; uint16_t tempw = 0; uint16_t src16; - uint8_t src, dst; + uint8_t src; + uint8_t dst; int8_t temps; fetch_ea_16(fetchdat); @@ -173,7 +174,8 @@ opF6_a32(uint32_t fetchdat) int tempws2 = 0; uint16_t tempw = 0; uint16_t src16; - uint8_t src, dst; + uint8_t src; + uint8_t dst; int8_t temps; fetch_ea_32(fetchdat); @@ -287,7 +289,7 @@ static int opF7_w_a16(uint32_t fetchdat) { uint32_t templ; - uint32_t templ2 = 0; + uint32_t templ2 = 0; int tempws; int tempws2 = 0; int16_t temps16; @@ -400,11 +402,12 @@ static int opF7_w_a32(uint32_t fetchdat) { uint32_t templ; - uint32_t templ2 = 0; + 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) @@ -514,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) @@ -606,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) @@ -739,7 +744,8 @@ opLOCK(uint32_t fetchdat) 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); @@ -761,7 +767,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); @@ -784,7 +791,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); @@ -806,7 +814,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 index 1afc4fba2..f26c903f9 100644 --- a/src/cpu/x86_ops_mmx.c +++ b/src/cpu/x86_ops_mmx.c @@ -23,11 +23,12 @@ #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" -#include "x86seg.h" -MMX_REG *MMP[8]; +MMX_REG *MMP[8]; uint16_t *MMEP[8]; static uint16_t MME[8]; @@ -40,10 +41,10 @@ mmx_init(void) for (uint8_t i = 0; i < 8; i++) { if (fpu_softfloat) { - MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction; + 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]); + 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 47751d059..ab5e19762 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -1,12 +1,12 @@ -#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_GETREG(r) *(MMP[r]) -#define MMX_SETEXP(r) \ +#define MMX_SETEXP(r) \ *(MMEP[r]) = 0xffff #define MMX_GETSRC() \ diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index 642e99c8a..099789970 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -1,7 +1,7 @@ static int opPADDB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -27,7 +27,7 @@ opPADDB_a16(uint32_t fetchdat) static int opPADDB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -54,7 +54,7 @@ opPADDB_a32(uint32_t fetchdat) static int opPADDW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -76,7 +76,7 @@ opPADDW_a16(uint32_t fetchdat) static int opPADDW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -99,7 +99,7 @@ opPADDW_a32(uint32_t fetchdat) static int opPADDD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -119,7 +119,7 @@ opPADDD_a16(uint32_t fetchdat) static int opPADDD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -140,7 +140,7 @@ opPADDD_a32(uint32_t fetchdat) static int opPADDSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -166,7 +166,7 @@ opPADDSB_a16(uint32_t fetchdat) static int opPADDSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -193,7 +193,7 @@ opPADDSB_a32(uint32_t fetchdat) static int opPADDUSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -219,7 +219,7 @@ opPADDUSB_a16(uint32_t fetchdat) static int opPADDUSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -246,7 +246,7 @@ opPADDUSB_a32(uint32_t fetchdat) static int opPADDSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -268,7 +268,7 @@ opPADDSW_a16(uint32_t fetchdat) static int opPADDSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -291,7 +291,7 @@ opPADDSW_a32(uint32_t fetchdat) static int opPADDUSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -313,7 +313,7 @@ opPADDUSW_a16(uint32_t fetchdat) static int opPADDUSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -336,7 +336,7 @@ opPADDUSW_a32(uint32_t fetchdat) static int opPMADDWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -363,7 +363,7 @@ opPMADDWD_a16(uint32_t fetchdat) static int opPMADDWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -391,7 +391,7 @@ opPMADDWD_a32(uint32_t fetchdat) static int opPMULLW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -422,7 +422,7 @@ opPMULLW_a16(uint32_t fetchdat) static int opPMULLW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -454,7 +454,7 @@ opPMULLW_a32(uint32_t fetchdat) static int opPMULHW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -485,7 +485,7 @@ opPMULHW_a16(uint32_t fetchdat) static int opPMULHW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -517,7 +517,7 @@ opPMULHW_a32(uint32_t fetchdat) static int opPSUBB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -543,7 +543,7 @@ opPSUBB_a16(uint32_t fetchdat) static int opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -570,7 +570,7 @@ opPSUBB_a32(uint32_t fetchdat) static int opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -592,7 +592,7 @@ opPSUBW_a16(uint32_t fetchdat) static int opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -615,7 +615,7 @@ opPSUBW_a32(uint32_t fetchdat) static int opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -635,7 +635,7 @@ opPSUBD_a16(uint32_t fetchdat) static int opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -656,7 +656,7 @@ opPSUBD_a32(uint32_t fetchdat) static int opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -682,7 +682,7 @@ opPSUBSB_a16(uint32_t fetchdat) static int opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -709,7 +709,7 @@ opPSUBSB_a32(uint32_t fetchdat) static int opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -735,7 +735,7 @@ opPSUBUSB_a16(uint32_t fetchdat) static int opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -762,7 +762,7 @@ opPSUBUSB_a32(uint32_t fetchdat) static int opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -784,7 +784,7 @@ opPSUBSW_a16(uint32_t fetchdat) static int opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -807,7 +807,7 @@ opPSUBSW_a32(uint32_t fetchdat) static int opPSUBUSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -829,7 +829,7 @@ opPSUBUSW_a16(uint32_t fetchdat) static int opPSUBUSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index b3081b8e8..141dba6bc 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -1,7 +1,7 @@ static int opPCMPEQB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -27,7 +27,7 @@ opPCMPEQB_a16(uint32_t fetchdat) static int opPCMPEQB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -54,7 +54,7 @@ opPCMPEQB_a32(uint32_t fetchdat) static int opPCMPGTB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -80,7 +80,7 @@ opPCMPGTB_a16(uint32_t fetchdat) static int opPCMPGTB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -107,7 +107,7 @@ opPCMPGTB_a32(uint32_t fetchdat) static int opPCMPEQW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -129,7 +129,7 @@ opPCMPEQW_a16(uint32_t fetchdat) static int opPCMPEQW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -152,7 +152,7 @@ opPCMPEQW_a32(uint32_t fetchdat) static int opPCMPGTW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -174,7 +174,7 @@ opPCMPGTW_a16(uint32_t fetchdat) static int opPCMPGTW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -197,7 +197,7 @@ opPCMPGTW_a32(uint32_t fetchdat) static int opPCMPEQD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -217,7 +217,7 @@ opPCMPEQD_a16(uint32_t fetchdat) static int opPCMPEQD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -238,7 +238,7 @@ opPCMPEQD_a32(uint32_t fetchdat) static int opPCMPGTD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -258,7 +258,7 @@ opPCMPGTD_a16(uint32_t fetchdat) static int opPCMPGTD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index 26d7c1693..617219845 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -1,7 +1,7 @@ static int opPAND_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -20,7 +20,7 @@ opPAND_a16(uint32_t fetchdat) static int opPAND_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -40,7 +40,7 @@ opPAND_a32(uint32_t fetchdat) static int opPANDN_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -59,7 +59,7 @@ opPANDN_a16(uint32_t fetchdat) static int opPANDN_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -79,7 +79,7 @@ opPANDN_a32(uint32_t fetchdat) static int opPOR_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -98,7 +98,7 @@ opPOR_a16(uint32_t fetchdat) static int opPOR_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -118,7 +118,7 @@ opPOR_a32(uint32_t fetchdat) static int opPXOR_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -137,7 +137,7 @@ opPXOR_a16(uint32_t fetchdat) static int opPXOR_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index 65bbb0c01..c72c8143d 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -115,7 +115,7 @@ opMOVD_mm_l_a32(uint32_t fetchdat) static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) { - MMX_REG *op; + const MMX_REG *op; if (in_smm) return opSMINT(fetchdat); @@ -144,7 +144,7 @@ opMOVD_mm_l_a16_cx(uint32_t fetchdat) static int opMOVD_mm_l_a32_cx(uint32_t fetchdat) { - MMX_REG *op; + const MMX_REG *op; if (in_smm) return opSMINT(fetchdat); @@ -176,14 +176,14 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat) { uint64_t dst; - MMX_REG src; + MMX_REG src; MMX_REG *op; MMX_ENTER(); fetch_ea_16(fetchdat); src = MMX_GETREG(cpu_rm); - op = MMX_GETREGP(cpu_reg); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { op->q = src.q; @@ -206,14 +206,14 @@ static int opMOVQ_q_mm_a32(uint32_t fetchdat) { uint64_t dst; - MMX_REG src; + MMX_REG src; MMX_REG *op; MMX_ENTER(); fetch_ea_32(fetchdat); src = MMX_GETREG(cpu_rm); - op = MMX_GETREGP(cpu_reg); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { op->q = src.q; @@ -236,7 +236,7 @@ opMOVQ_q_mm_a32(uint32_t fetchdat) static int opMOVQ_mm_q_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -266,7 +266,7 @@ opMOVQ_mm_q_a16(uint32_t fetchdat) static int opMOVQ_mm_q_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index 90590638b..90ed1b6d2 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -2,7 +2,7 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat) { uint32_t usrc; - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -32,7 +32,7 @@ static int opPUNPCKLDQ_a32(uint32_t fetchdat) { uint32_t usrc; - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -62,7 +62,7 @@ opPUNPCKLDQ_a32(uint32_t fetchdat) static int opPUNPCKHDQ_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -82,7 +82,7 @@ opPUNPCKHDQ_a16(uint32_t fetchdat) static int opPUNPCKHDQ_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -103,7 +103,7 @@ opPUNPCKHDQ_a32(uint32_t fetchdat) static int opPUNPCKLBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -129,7 +129,7 @@ opPUNPCKLBW_a16(uint32_t fetchdat) static int opPUNPCKLBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -156,7 +156,7 @@ opPUNPCKLBW_a32(uint32_t fetchdat) static int opPUNPCKHBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -182,7 +182,7 @@ opPUNPCKHBW_a16(uint32_t fetchdat) static int opPUNPCKHBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -209,7 +209,7 @@ opPUNPCKHBW_a32(uint32_t fetchdat) static int opPUNPCKLWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -231,7 +231,7 @@ opPUNPCKLWD_a16(uint32_t fetchdat) static int opPUNPCKLWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -254,7 +254,7 @@ opPUNPCKLWD_a32(uint32_t fetchdat) static int opPUNPCKHWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -276,7 +276,7 @@ opPUNPCKHWD_a16(uint32_t fetchdat) static int opPUNPCKHWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -299,7 +299,7 @@ opPUNPCKHWD_a32(uint32_t fetchdat) static int opPACKSSWB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -325,7 +325,7 @@ opPACKSSWB_a16(uint32_t fetchdat) static int opPACKSSWB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -352,7 +352,7 @@ opPACKSSWB_a32(uint32_t fetchdat) static int opPACKUSWB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -378,7 +378,7 @@ opPACKUSWB_a16(uint32_t fetchdat) static int opPACKUSWB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; MMX_ENTER(); @@ -405,14 +405,14 @@ opPACKUSWB_a32(uint32_t fetchdat) static int opPACKSSDW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; - MMX_REG dst2; + MMX_REG dst2; MMX_ENTER(); fetch_ea_16(fetchdat); - dst = MMX_GETREGP(cpu_reg); + dst = MMX_GETREGP(cpu_reg); dst2 = *dst; MMX_GETSRC(); @@ -429,14 +429,14 @@ opPACKSSDW_a16(uint32_t fetchdat) static int opPACKSSDW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; MMX_REG *dst; - MMX_REG dst2; + MMX_REG dst2; MMX_ENTER(); fetch_ea_32(fetchdat); - dst = MMX_GETREGP(cpu_reg); + dst = MMX_GETREGP(cpu_reg); dst2 = *dst; MMX_GETSRC(); diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index c0c80e87e..04aeb8a9a 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -13,9 +13,9 @@ 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; @@ -67,7 +67,7 @@ static int opPSLLW_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -94,7 +94,7 @@ static int opPSLLW_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -122,7 +122,7 @@ static int opPSRLW_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -149,7 +149,7 @@ static int opPSRLW_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -177,7 +177,7 @@ static int opPSRAW_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -203,7 +203,7 @@ static int opPSRAW_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -229,9 +229,9 @@ 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; @@ -278,7 +278,7 @@ static int opPSLLD_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -303,7 +303,7 @@ static int opPSLLD_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -329,7 +329,7 @@ static int opPSRLD_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -354,7 +354,7 @@ static int opPSRLD_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -380,7 +380,7 @@ static int opPSRAD_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -404,7 +404,7 @@ static int opPSRAD_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -428,9 +428,9 @@ 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; @@ -474,7 +474,7 @@ static int opPSLLQ_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -497,7 +497,7 @@ static int opPSLLQ_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -521,7 +521,7 @@ static int opPSRLQ_a16(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); @@ -544,7 +544,7 @@ static int opPSRLQ_a32(uint32_t fetchdat) { MMX_REG *dst; - int shift; + int shift; MMX_ENTER(); diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index 063a33516..e77876d5c 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 d95116c93..b0c841f83 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_seg.h b/src/cpu/x86_ops_mov_seg.h index c6bfd9933..2a798db5c 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; @@ -198,10 +198,10 @@ opMOV_seg_w_a16(uint32_t fetchdat) x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); 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 +223,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; @@ -243,10 +243,10 @@ opMOV_seg_w_a32(uint32_t fetchdat) x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); 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 +258,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 +269,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 +281,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 +292,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 +315,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 +338,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 +351,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 +362,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 +374,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 +385,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 +408,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 +431,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 +454,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 +476,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 +499,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 +522,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 +536,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 552a9973a..aa7526e75 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 c8e146450..1254d7289 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,7 +362,9 @@ 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*/ if (cpu_mod != 3) diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu/x86_ops_prefix.h index eba59c17a..8a7357386 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_rep_2386.h b/src/cpu/x86_ops_rep_2386.h new file mode 100644 index 000000000..b6f64e90d --- /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(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(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 ec200f2d7..0d9a6370b 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_set.h b/src/cpu/x86_ops_set.h index 30c076a6e..75caa4491 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 9c11a32f0..1394cf420 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 8217a9e5a..13eb883d3 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; @@ -643,7 +679,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; diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index c9ba94760..619386fcb 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 000000000..98875e54f --- /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 c5ce08999..70e7be58c 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 7f630275c..96061d3fa 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,12 @@ 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); -} - 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 +93,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 +113,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 +139,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 +161,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 +196,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 +211,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 +245,7 @@ check_seg_valid(x86seg *s) } if (!valid) - loadseg(0, s); + op_loadseg(0, s); } static void @@ -332,12 +271,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 +473,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 +566,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 +698,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 +730,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 +757,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc) } } -void +static void PUSHW(uint16_t v) { if (stack32) { @@ -818,7 +773,7 @@ PUSHW(uint16_t v) } } -void +static void PUSHL(uint32_t v) { if (cpu_16bitbus) { @@ -839,7 +794,7 @@ PUSHL(uint32_t v) } } -uint16_t +static uint16_t POPW(void) { uint16_t tempw; @@ -857,7 +812,7 @@ POPW(void) return tempw; } -uint32_t +static uint32_t POPL(void) { uint32_t templ; @@ -882,6 +837,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 +853,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 +1147,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 +1182,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 +1208,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 +1448,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 +1483,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 +1624,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 +1653,7 @@ pmodeint(int num, int soft) x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc); return; } - /*FALLTHROUGH*/ + fallthrough; case 0x1c00: case 0x1d00: case 0x1e00: @@ -1737,7 +1729,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 +1740,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 +1796,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 +1811,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 +1847,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 +1872,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 +2059,38 @@ 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 addr; + uint32_t *segdat232 = (uint32_t *) segdat2; + const x86seg *dt; base = segdat[1] | ((segdat[2] & 0x00ff) << 16); limit = segdat[0]; @@ -2186,7 +2210,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 +2274,11 @@ 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); } else { if (limit < 43) { x86ts(NULL, seg); @@ -2416,12 +2440,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); } } @@ -2433,7 +2457,11 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } 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 +2473,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 715251f2d..dcc8c9ef8 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/cpu/x86seg_2386.c b/src/cpu/x86seg_2386.c new file mode 100644 index 000000000..335c757e4 --- /dev/null +++ b/src/cpu/x86seg_2386.c @@ -0,0 +1,22 @@ +/* + * 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 for the 286/386 interpreter. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#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 000000000..8926af0d7 --- /dev/null +++ b/src/cpu/x86seg_common.c @@ -0,0 +1,123 @@ +/* + * 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 +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 000000000..f4bffed40 --- /dev/null +++ b/src/cpu/x86seg_common.h @@ -0,0 +1,52 @@ +/* + * 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 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 181b7b9ca..1f7643453 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; } } @@ -444,14 +450,22 @@ 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; + 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; } @@ -461,45 +475,45 @@ 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: + /* 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 | + | 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. - */ + * + * 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) { diff --git a/src/cpu/x87.h b/src/cpu/x87.h index 66d51dbd9..f4e24f1ca 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -3,8 +3,10 @@ #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) @@ -14,9 +16,9 @@ x87_set_mmx(void) 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.TOP = 0; + p = (uint64_t *) cpu_state.tag; + *p = 0x0101010101010101ULL; } cpu_state.ismmx = 1; } @@ -29,8 +31,8 @@ x87_emms(void) fpu_state.tag = 0xffff; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } else { - p = (uint64_t *) cpu_state.tag; - *p = 0; + p = (uint64_t *) cpu_state.tag; + *p = 0; } cpu_state.ismmx = 0; } @@ -58,101 +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 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 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_CC (C0 | C1 | C2 | C3) -#define FPU_SW_Exceptions_Mask (0x027f) /* status word exceptions bit mask */ +#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); -uint8_t pack_FPU_TW(uint16_t twd); -uint16_t unpack_FPU_TW(uint16_t tag_byte); +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) @@ -179,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 @@ -226,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 e321df959..1d9220255 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 d38d584a8..808a15051 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 bb1e497da..7a949cfb2 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 9cec01490..d77c0ca2b 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 bd2b05c52..d854f83db 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 e70556fea..137919fa9 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; + 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; + 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; + 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; + 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; + 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 10b100b2a..5144062bb 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: static int sf_FSQRT(uint32_t fetchdat) { - floatx80 result; + floatx80 result; struct float_status_t status; FP_ENTER(); @@ -726,7 +761,7 @@ next_ins: 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 59135c05b..6b4c1cb62 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 708c6ff7a..0808cbae8 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 69bc5598c..383a7ee52 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 d8a3d7368..85f42e6d5 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 5289b2bbf..5a99abb4c 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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 @@ next_ins: 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/cpu/x886seg_2386.c b/src/cpu/x886seg_2386.c new file mode 100644 index 000000000..335c757e4 --- /dev/null +++ b/src/cpu/x886seg_2386.c @@ -0,0 +1,22 @@ +/* + * 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 for the 286/386 interpreter. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#ifndef OPS_286_386 +# define OPS_286_386 +#endif +#include "x86seg.c" diff --git a/src/device.c b/src/device.c index e9d0a094a..c517f98e9 100644 --- a/src/device.c +++ b/src/device.c @@ -39,6 +39,7 @@ * Boston, MA 02111-1307 * USA. */ +#include #include #include #include @@ -158,6 +159,8 @@ device_add_common(const device_t *dev, const device_t *cd, void *p, void *params /* Do this so that a chained device_add will not identify the same ID its master device is already trying to assign. */ devices[c] = (device_t *) dev; + if (!strcmp(dev->name, "None") || !strcmp(dev->name, "Internal")) + fatal("Attempting to add dummy device of type: %s\n", dev->name); if (p == NULL) { memcpy(&device_prev, &device_current, sizeof(device_context_t)); @@ -191,13 +194,13 @@ device_add_common(const device_t *dev, const device_t *cd, void *p, void *params return priv; } -char * +const char * device_get_internal_name(const device_t *dev) { if (dev == NULL) return ""; - return (char *) dev->internal_name; + return dev->internal_name; } void * @@ -327,6 +330,23 @@ device_reset_all(uint32_t match_flags) } } +void * +device_find_first_priv(uint32_t match_flags) +{ + void *ret = NULL; + + for (uint16_t c = 0; c < DEVICE_MAX; c++) { + if (devices[c] != NULL) { + if ((device_priv[c] != NULL) && (devices[c]->flags & match_flags)) { + ret = device_priv[c]; + break; + } + } + } + + return ret; +} + void * device_get_priv(const device_t *dev) { @@ -439,13 +459,13 @@ device_has_config(const device_t *dev) } int -device_poll(const device_t *dev, 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] == 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])); } } } @@ -453,22 +473,6 @@ device_poll(const device_t *dev, int x, int y, int z, int b) return 0; } -void -device_register_pci_slot(const device_t *dev, int device, int type, int inta, int intb, int intc, int intd) -{ - for (uint16_t c = 0; c < DEVICE_MAX; c++) { - if (devices[c] != NULL) { - if (devices[c] == dev) { - if (devices[c]->register_pci_slot) - devices[c]->register_pci_slot(device, type, inta, intb, intc, intd, device_priv[c]); - return; - } - } - } - - return; -} - void device_get_name(const device_t *dev, int bus, char *name) { @@ -566,6 +570,8 @@ device_speed_changed(void) { for (uint16_t c = 0; c < DEVICE_MAX; c++) { if (devices[c] != NULL) { + device_log("DEVICE: device '%s' speed changed\n", devices[c]->name); + if (devices[c]->speed_changed != NULL) devices[c]->speed_changed(device_priv[c]); } @@ -747,27 +753,51 @@ 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; diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index ef3a392ee..24a9d7ac4 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 + postcard.c serial.c unittester.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c smbus_piix4.c smbus_ali7101.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/cartridge.c b/src/device/cartridge.c index 5d8e6cc4c..edabd3ed0 100644 --- a/src/device/cartridge.c +++ b/src/device/cartridge.c @@ -90,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); @@ -107,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); @@ -136,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 17b650e81..1d0b88531 100644 --- a/src/device/cassette.c +++ b/src/device/cassette.c @@ -650,9 +650,9 @@ cassette_close(UNUSED(void *priv)) } 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); diff --git a/src/device/clock_ics9xxx.c b/src/device/clock_ics9xxx.c index 21a4c14ba..263170741 100644 --- a/src/device/clock_ics9xxx.c +++ b/src/device/clock_ics9xxx.c @@ -99,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 }; @@ -1010,7 +1010,7 @@ ics9xxx_read(UNUSED(void *bus), UNUSED(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]; @@ -1079,32 +1079,32 @@ ics9xxx_write(UNUSED(void *bus), UNUSED(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; + 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 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 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 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; - } + case 6: + if (dev->model_idx == ICS9250_38) /* read-only */ + data = dev->regs[dev->addr_register]; + break; + } #endif dev->regs[dev->addr_register] = data; @@ -1117,20 +1117,20 @@ ics9xxx_write(UNUSED(void *bus), UNUSED(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_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_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_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/hwm_gl518sm.c b/src/device/hwm_gl518sm.c index 01f917b32..6ba1083d9 100644 --- a/src/device/hwm_gl518sm.c +++ b/src/device/hwm_gl518sm.c @@ -31,11 +31,13 @@ #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)) +#define GL520SM 0x100 + typedef struct gl518sm_t { uint32_t local; hwm_values_t *values; @@ -128,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; @@ -217,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; @@ -238,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; @@ -279,7 +296,8 @@ gl518sm_init(const device_t *info) }, { /* temperatures */ - 30 /* usually CPU */ + 30, /* usually CPU */ + 30 /* GL520SM only: usually System */ }, { /* voltages */ @@ -327,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_lm78.c b/src/device/hwm_lm78.c index 74752a089..f3003db26 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -27,6 +27,7 @@ #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> @@ -105,13 +106,13 @@ 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); @@ -136,7 +137,7 @@ lm78_nvram_read(UNUSED(void *bus), UNUSED(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; diff --git a/src/device/isapnp.c b/src/device/isapnp.c index 22b22dfcc..f9d10b380 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -29,29 +29,21 @@ #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 @@ -95,6 +87,7 @@ typedef struct _isapnp_card_ { 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; @@ -131,7 +124,7 @@ 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. */ @@ -183,7 +176,7 @@ isapnp_reset_ld_config(isapnp_device_t *ld) /* Populate configuration registers. */ ld->regs[0x30] = !!config->activate; - uint8_t reg_base; + uint8_t reg_base; uint32_t size; for (uint8_t i = 0; i < 4; i++) { reg_base = 0x40 + (8 * i); @@ -265,15 +258,13 @@ isapnp_read_rangecheck(UNUSED(uint16_t addr), void *priv) } static uint8_t -isapnp_read_data(UNUSED(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) { @@ -342,78 +333,52 @@ isapnp_read_data(UNUSED(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) { @@ -445,7 +410,7 @@ isapnp_write_addr(UNUSED(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"); @@ -462,17 +427,14 @@ isapnp_write_addr(UNUSED(uint16_t addr), uint8_t val, void *priv) } static void -isapnp_write_data(UNUSED(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); @@ -526,7 +488,7 @@ isapnp_write_data(UNUSED(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 { @@ -551,6 +513,7 @@ isapnp_write_data(UNUSED(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) { @@ -570,10 +533,10 @@ isapnp_write_data(UNUSED(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; @@ -581,80 +544,39 @@ isapnp_write_data(UNUSED(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: @@ -664,7 +586,7 @@ isapnp_write_data(UNUSED(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: @@ -676,21 +598,21 @@ isapnp_write_data(UNUSED(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; @@ -699,13 +621,31 @@ isapnp_write_data(UNUSED(uint16_t addr), uint8_t val, void *priv) 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(UNUSED(const device_t *info)) { @@ -795,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. @@ -838,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 { @@ -852,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; @@ -874,14 +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; -#else - default: - break; -#endif } i += 3; /* header */ @@ -890,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]); @@ -931,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; @@ -963,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); @@ -972,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; @@ -1014,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; @@ -1042,9 +1018,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; default: -#ifdef ENABLE_ISAPNP_LOG isapnp_log("ISAPnP: >%s%s Small resource %02X (length %d)\n", ldn ? ">" : "", in_df ? ">" : "", res, card->rom[i] & 0x07); -#endif break; } @@ -1101,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 ce0fcd7c6..46f31c137 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -789,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 60b4a2b3f..d2e6cf364 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -25,10 +25,12 @@ #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> @@ -42,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 @@ -127,6 +132,10 @@ typedef struct atkbc_t { 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]; @@ -135,8 +144,9 @@ typedef struct atkbc_t { 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; @@ -144,8 +154,8 @@ typedef struct atkbc_t { /* 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. */ @@ -346,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; } @@ -463,9 +473,7 @@ kbc_at_poll_at(atkbc_t *dev) case STATE_KBC_AMI_OUT: if (dev->status & STAT_OFULL) break; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case STATE_MAIN_IBF: default: at_main_ibf: @@ -499,7 +507,6 @@ at_main_ibf: 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) { @@ -588,9 +595,7 @@ kbc_at_poll_ps2(atkbc_t *dev) case STATE_KBC_AMI_OUT: if (dev->status & STAT_OFULL) break; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case STATE_MAIN_IBF: default: ps2_main_ibf: @@ -645,7 +650,6 @@ ps2_main_ibf: 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) { @@ -695,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); @@ -719,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 @@ -736,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"); @@ -758,13 +770,35 @@ write_p2(atkbc_t *dev, uint8_t val) correctly despite A20 being gated when the CPU is reset, this will have to do. */ else if (kbc_ven == KBC_VEN_SIEMENS) - loadcs(0xF000); + 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 @@ -878,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); @@ -917,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. @@ -1549,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; @@ -1568,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; @@ -1851,7 +1890,7 @@ 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); break; case 0x64: @@ -1900,8 +1939,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; @@ -1923,10 +1967,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) { @@ -1958,9 +2001,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; diff --git a/src/device/kbc_at_dev.c b/src/device/kbc_at_dev.c index c37ddda9d..1c1a0e91a 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; @@ -135,9 +136,7 @@ kbc_at_dev_poll(void *priv) dev->port->wantcmd = 0; break; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + 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)) { diff --git a/src/device/keyboard.c b/src/device/keyboard.c index e788ff23f..5f9986d7b 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 */ @@ -167,6 +186,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; default: break; @@ -191,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; @@ -338,15 +369,15 @@ 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 3b167d66f..f8eddb931 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, @@ -73,6 +77,8 @@ 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*/ @@ -702,11 +708,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 @@ -924,6 +935,7 @@ keyboard_at_write(void *priv) case 0xff: /* reset */ kbc_at_dev_reset(dev, 1); + bat_counter = 1000; break; default: @@ -963,8 +975,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 a5b5579a6..f65a6dffc 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -54,19 +54,22 @@ #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 +/* 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; @@ -530,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; @@ -540,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(); @@ -599,12 +602,19 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: /* Keyboard Data Register (aka Port A) */ - if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) || - (kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_ZENITH))) { - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_PRAVETZ)) + if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || + (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || + (kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || + (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || + (kbd->type == KBD_TYPE_ZENITH) || (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: @@ -633,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: @@ -648,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; @@ -662,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 @@ -673,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 @@ -687,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; @@ -753,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 @@ -773,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; @@ -1068,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 2acfd905e..193149bc8 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,6 +32,8 @@ #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 mouse_t { @@ -37,17 +41,16 @@ typedef struct mouse_t { } 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 = { @@ -84,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; @@ -123,84 +137,377 @@ 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_type = MOUSE_TYPE_NONE; - mouse_curr = NULL; - mouse_priv = NULL; - mouse_nbut = 0; - mouse_dev_poll = NULL; + mouse_x = 0.0; } void -mouse_close(void) +mouse_clear_y(void) { - if (mouse_curr == NULL) - return; + mouse_y = 0.0; +} - mouse_curr = NULL; - mouse_priv = NULL; - mouse_nbut = 0; - mouse_dev_poll = NULL; +void +mouse_clear_coords(void) +{ + mouse_clear_x(); + mouse_clear_y(); - timer_stop(&mouse_timer); + mouse_z = 0; +} + +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(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_scale_fx(double x) +{ + atomic_double_add(&mouse_x, ((double) x) * mouse_sensitivity); +} + +void +mouse_scale_fy(double y) +{ + atomic_double_add(&mouse_y, ((double) y) * mouse_sensitivity); +} + +void +mouse_scale_x(int x) +{ + atomic_double_add(&mouse_x, ((double) x) * mouse_sensitivity); +} + +void +mouse_scale_y(int y) +{ + atomic_double_add(&mouse_y, ((double) y) * mouse_sensitivity); +} + +void +mouse_scalef(double x, double y) +{ + mouse_scale_fx(x); + mouse_scale_fy(y); +} + +void +mouse_scale(int x, int y) +{ + mouse_scale_x(x); + mouse_scale_y(y); +} + +void +mouse_set_z(int z) +{ + atomic_fetch_add(&mouse_z, z); +} + +void +mouse_clear_z(void) +{ + atomic_store(&mouse_z, 0); +} + +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; - timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); -} - -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_x = mouse_y = mouse_z = 0; - mouse_buttons = 0x00; - mouse_mode = 0; - - /* 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_curr != NULL) - mouse_priv = device_add(mouse_curr); + if (mouse_timed) + timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); } /* Callback from the hardware driver. */ @@ -211,9 +518,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 @@ -222,24 +530,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; @@ -248,13 +556,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); @@ -301,3 +609,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 0537c0cb4..554704c9d 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,7 @@ #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> @@ -147,8 +149,6 @@ typedef struct mouse { int irq; int bn; int flags; - int mouse_delayed_dx; - int mouse_delayed_dy; int mouse_buttons; int mouse_buttons_last; int toggle_counter; @@ -475,16 +475,22 @@ ms_write(uint16_t port, uint8_t val, void *priv) /* The emulator calls us with an update on the host mouse device. */ static int -bm_poll(int x, int y, UNUSED(int z), int b, UNUSED(double abs_x), UNUSED(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. */ } @@ -498,36 +504,23 @@ bm_poll(int x, int y, UNUSED(int z), int b, UNUSED(double abs_x), UNUSED(double 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; } @@ -538,6 +531,7 @@ bm_poll(int x, int y, UNUSED(int z), int b, UNUSED(double abs_x), UNUSED(double bm_log("DEBUG: Data Interrupt Fired...\n"); } } + return 0; } @@ -548,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; @@ -659,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 */ @@ -707,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 2d150b5ed..35f0cd9e8 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 @@ -23,6 +24,7 @@ #include <86box/device.h> #include <86box/keyboard.h> #include <86box/mouse.h> +#include <86box/plat.h> #include <86box/plat_unused.h> enum { @@ -73,56 +75,41 @@ static void ps2_report_coordinates(atkbc_dev_t *dev, int main) { uint8_t buff[3] = { 0x08, 0x00, 0x00 }; - int temp_z; + int delta_x; + int delta_y; + int overflow_x; + int overflow_y; + int b = mouse_get_buttons_ex(); + int delta_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; + mouse_subtract_coords(&delta_x, &delta_y, &overflow_x, &overflow_y, + -256, 255, 1, 0); + mouse_subtract_z(&delta_z, -8, 7, 1); - 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); + 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 @@ -132,7 +119,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; } @@ -151,6 +138,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 }; @@ -209,15 +197,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); @@ -311,30 +300,18 @@ ps2_write(void *priv) } static int -ps2_poll(int x, int y, int z, int b, UNUSED(double abs_x), UNUSED(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; + 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))) { - 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; - } - - 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; } /* @@ -358,9 +335,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 ad3b8f7cb..08aee09d8 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,65 +27,79 @@ #include <86box/timer.h> #include <86box/serial.h> #include <86box/mouse.h> -#include <86box/plat_unused.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 mouse_t { const char *name; /* name of this device */ - int8_t type; /* type of this device */ - int8_t port; + + uint8_t id[252]; + uint8_t buf[256]; + uint8_t flags; /* device flags */ uint8_t but; - uint8_t want_data; + uint8_t rts_toggle; uint8_t status; uint8_t format; uint8_t prompt; - uint8_t on_change; + + uint8_t continuous; + uint8_t ib; + uint8_t command; + uint8_t buf_len; + uint8_t report_mode; uint8_t id_len; - uint8_t id[255]; - uint8_t data_len; - uint8_t data[5]; - int abs_x; - int abs_y; - int rel_x; - int rel_y; - int rel_z; - int oldb; - int lastb; + uint8_t buf_pos; + uint8_t rev; - int command_pos; - int command_phase; - int report_pos; - int report_phase; - int command_enabled; - int report_enabled; - double transmit_period; - double report_period; - double auto_period; - pc_timer_t command_timer; - pc_timer_t report_timer; + int8_t type; /* type of this device */ + int8_t port; - serial_t *serial; + 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 */ @@ -111,63 +126,672 @@ 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; + dev->cur_period = period; /* Needed for the recalculation of the timings. */ - if (report) { - timer = &dev->report_timer; - enabled = &dev->report_enabled; - } else { - timer = &dev->command_timer; - enabled = &dev->command_enabled; - } + timer_stop(&dev->timer); - timer_on_auto(timer, period); - - *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; + + serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]); + + if (do_next) { + dev->buf_pos = (dev->buf_pos + 1) % dev->buf_len; + + if (dev->buf_pos != 0) + sermouse_set_period(dev, dev->transmit_period); + } +} + +static void +sermouse_transmit(mouse_t *dev, int len, int from_report, int to_report) +{ + 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_report_msystems(mouse_t *dev) +{ + 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_report_3bp(mouse_t *dev) +{ + 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_report_mmseries(mouse_t *dev) +{ + 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_report_bp1(mouse_t *dev, int abs) +{ + 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_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->buf[0] = 0x40; + dev->buf[0] |= (((delta_y >> 6) & 0x03) << 2); + dev->buf[0] |= ((delta_x >> 6) & 0x03); + if (b & 0x01) + dev->buf[0] |= 0x20; + if (b & 0x02) + 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->format == FORMAT_MS) { + if (b & 0x04) { + dev->buf[3] = 0x20; + len++; + } + } else { + if (mouse_mbut_changed()) { + /* Microsoft 3-button mice send a fourth byte of 0x00 when the middle button + has changed. */ + dev->buf[3] = 0x00; + len++; + } + } + } else if (dev->but == 4) { + len = 4; + + dev->buf[3] = delta_z & 0x0f; + if (b & 0x04) + dev->buf[3] |= 0x10; + } else + len = 3; + + return len; +} + +static uint8_t +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 */ + if (dev->but >= 3) + but |= (b & 0x04) ? 0x02 : 0x00; /* middle button */ + but |= (b & 0x02) ? 0x01 : 0x00; /* right button */ + + sprintf(ret, "%01X%02X%02X", but & 0x0f, (int8_t) delta_x, (int8_t) delta_y); + + memcpy(dev->buf, ret, 5); + + return 5; +} + +static int +sermouse_report(mouse_t *dev) +{ + int len = 0; + + memset(dev->buf, 0, 5); 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; + case FORMAT_PB_5BYTE: + len = sermouse_report_msystems(dev); 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; + case FORMAT_PB_3BYTE: + len = sermouse_report_3bp(dev); + break; + case FORMAT_HEX: + len = sermouse_report_hex(dev); + break; + case FORMAT_BP1_REL: + len = sermouse_report_bp1(dev, 0); + break; + case FORMAT_MM_SERIES: + len = sermouse_report_mmseries(dev); + break; + case FORMAT_BP1_ABS: + len = sermouse_report_bp1(dev, 1); + break; + case FORMAT_MS: + case FORMAT_MS_4BYTE: + case FORMAT_MS_WHEEL: + len = sermouse_report_ms(dev); + break; + + default: + break; + } + + return len; +} + +static void +sermouse_transmit_report(mouse_t *dev, int from_report) +{ + 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 int +sermouse_poll(void *priv) +{ + 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 void +ltsermouse_set_prompt_mode(mouse_t *dev, int prompt) +{ + dev->prompt = prompt; + + if (prompt || dev->continuous) + sermouse_set_period(dev, 0.0); + else + sermouse_set_period(dev, dev->transmit_period); +} + +static void +ltsermouse_set_report_period(mouse_t *dev, int rps) +{ + /* Limit the reports rate according to the baud rate. */ + if (rps == 0) { + sermouse_set_period(dev, 0.0); + + dev->report_period = 0.0; + dev->continuous = 1; + } else { +#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. */ + } +} + +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 void +ltsermouse_switch_baud_rate(mouse_t *dev, int next_state) +{ + 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 + + if (next_state == STATE_BAUD_RATE) + dev->transmit_period = dev->host_transmit_period; + else + dev->transmit_period = 1000000.0 / ((double) dev->bps); + + dev->min_bit_period = dev->transmit_period; + + 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 + + ltsermouse_set_report_period(dev, dev->rps); + + if (!dev->continuous && (next_state != STATE_BAUD_RATE)) { + if (dev->prompt) + ltsermouse_set_prompt_mode(dev, 0); + + sermouse_transmit_report(dev, 0); + } + + dev->state = next_state; +} + +static int +sermouse_next_state(mouse_t *dev) +{ + int ret = STATE_IDLE; + + if (dev->prompt || (dev->rps == 0)) + ret = STATE_IDLE; + else + ret = STATE_TRANSMIT; + + return ret; +} + +static void +ltsermouse_process_command(mouse_t *dev) +{ + 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; + + 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; + + 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; + + 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 0x2a: + if (dev->rev >= 0x03) { + /* Programmable Baud Rate Selection */ + dev->state = STATE_DATA; + } + break; + + case 0x73: + /* Status */ + dev->buf[0] = dev->prompt ? 0x4f : 0x0f; + sermouse_transmit(dev, 1, 0, 0); + break; + 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; + + 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; + + 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; + + 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; + + case 0x64: + /* Dormant State */ + dev->state = STATE_DORMANT; + break; + + case 0x6b: + /* Buttons - 86Box-specific command. */ + dev->state = dev->but; + break; + + default: + break; + } +} + +static void +ltsermouse_process_data(mouse_t *dev) +{ + 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 +sermouse_reset(mouse_t *dev, int callback) +{ + 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: - case 6: /* Bit Pad One formats: 7 data, even parity, 2 stop, 1 start */ - word_len = 11; + dev->format = (dev->type == MOUSE_TYPE_LT3BUTTON) ? FORMAT_MS : FORMAT_MS_4BYTE; break; - case 5: /* MM Series format: 8 data, odd parity, 1 stop, 1 start */ - word_len = 11; + case 4: + dev->format = FORMAT_MS_WHEEL; + break; + } + + ltsermouse_switch_baud_rate(dev, callback ? STATE_TRANSMIT : STATE_IDLE); +} + +static void +sermouse_timer(void *priv) +{ + 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; - case 7: /* Microsoft-compatible format: 7 data, no parity, 1 stop, 1 start */ default: - word_len = 9; break; } - if (rps == -1) - temp = (double) word_len; - else { - temp = (double) rps; - temp = (9600.0 - (temp * 33.0)); - temp /= rps; - } - temp = (1000000.0 / dbps) * temp; + mouse_serial_log("sermouse_timer(): %02i -> %02i\n", old_state, dev->state); +} - return temp; +static void +ltsermouse_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) +{ + 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. */ @@ -176,585 +800,10 @@ sermouse_callback(UNUSED(struct serial_s *serial), void *priv) { 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 -} + sermouse_reset(dev, 1); -static uint8_t -sermouse_data_msystems(mouse_t *dev, int x, int y, int b) -{ - 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 */ - - return 5; -} - -static uint8_t -sermouse_data_3bp(mouse_t *dev, int x, int y, int b) -{ - 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; - - return 3; -} - -static uint8_t -sermouse_data_mmseries(mouse_t *dev, int x, int y, int b) -{ - 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; - - return 3; -} - -static uint8_t -sermouse_data_bp1(mouse_t *dev, int x, int y, int b) -{ - 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); - - return 5; -} - -static uint8_t -sermouse_data_ms(mouse_t *dev, int x, int y, int z, int b) -{ - uint8_t len; - - dev->data[0] = 0x40; - dev->data[0] |= (((y >> 6) & 0x03) << 2); - dev->data[0] |= ((x >> 6) & 0x03); - if (b & 0x01) - dev->data[0] |= 0x20; - if (b & 0x02) - dev->data[0] |= 0x10; - dev->data[1] = x & 0x3F; - dev->data[2] = y & 0x3F; - if (dev->but == 3) { - len = 3; - if (dev->type == MOUSE_TYPE_LT3BUTTON) { - if (b & 0x04) { - dev->data[3] = 0x20; - len++; - } - } else { - if ((b ^ dev->oldb) & 0x04) { - /* Microsoft 3-button mice send a fourth byte of 0x00 when the middle button - has changed. */ - dev->data[3] = 0x00; - len++; - } - } - } else if (dev->but == 4) { - len = 4; - dev->data[3] = z & 0x0F; - if (b & 0x04) - dev->data[3] |= 0x10; - } else - len = 3; - - return len; -} - -static uint8_t -sermouse_data_hex(mouse_t *dev, int x, int y, int b) -{ - char ret[6] = { 0, 0, 0, 0, 0, 0 }; - uint8_t but = 0x00; - - but |= (b & 0x01) ? 0x04 : 0x00; /* left button */ - 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); - - for (uint8_t i = 0; i < 5; i++) - dev->data[i] = ret[4 - i]; - - return 5; -} - -static void -sermouse_report(int x, int y, int z, int b, 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; - - switch (dev->format) { - case 0: - len = sermouse_data_msystems(dev, x, y, b); - break; - case 1: - len = sermouse_data_3bp(dev, x, y, b); - break; - case 2: - len = sermouse_data_hex(dev, x, y, b); - break; - case 3: /* Relative */ - len = sermouse_data_bp1(dev, x, y, b); - break; - case 5: - len = sermouse_data_mmseries(dev, x, y, b); - break; - case 6: /* Absolute */ - len = sermouse_data_bp1(dev, dev->abs_x, dev->abs_y, b); - break; - case 7: - len = sermouse_data_ms(dev, x, y, z, b); - break; - - default: - break; - } - - dev->data_len = len; -} - -static void -sermouse_command_phase_idle(mouse_t *dev) -{ - dev->command_pos = 0; - dev->command_phase = PHASE_IDLE; - dev->command_enabled = 0; -} - -static void -sermouse_command_pos_check(mouse_t *dev, int len) -{ - if (++dev->command_pos == len) - sermouse_command_phase_idle(dev); - else - timer_on_auto(&dev->command_timer, dev->transmit_period); -} - -static uint8_t -sermouse_last_button_status(mouse_t *dev) -{ - uint8_t ret = 0x00; - - if (dev->oldb & 0x01) - ret |= 0x04; - if (dev->oldb & 0x02) - ret |= 0x02; - if (dev->oldb & 0x04) - ret |= 0x01; - - return ret; -} - -static void -sermouse_update_delta(mouse_t *dev, int *local, int *global) -{ - int min; - int max; - - if (dev->format == 3) { - min = -2048; - max = 2047; - } else { - min = -128; - max = 127; - } - - if (*global > max) { - *local = max; - *global -= max; - } else if (*global < min) { - *local = min; - *global += -min; - } else { - *local = *global; - *global = 0; - } -} - -static uint8_t -sermouse_update_data(mouse_t *dev) -{ - uint8_t ret = 0; - int delta_x; - int delta_y; - int delta_z; - - /* 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); - - sermouse_report(delta_x, delta_y, delta_z, dev->oldb, dev); - - mouse_serial_log("delta_x = %i, delta_y = %i, delta_z = %i, dev->oldb = %02X\n", - delta_x, delta_y, delta_z, dev->oldb); - - if (delta_x || delta_y || delta_z || (dev->oldb != dev->lastb) || !dev->on_change) - ret = 1; - - dev->lastb = dev->oldb; - - mouse_serial_log("sermouse_update_data(): ret = %i\n", ret); - - return ret; -} - -static double -sermouse_report_period(mouse_t *dev) -{ - if (dev->report_period == 0) - return dev->transmit_period; - else - return dev->report_period; -} - -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); - } -} - -static void -sermouse_report_timer(void *priv) -{ - mouse_t *dev = (mouse_t *) priv; - - 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); - } -} - -/* 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; - - 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); - } - break; - case PHASE_ACK: - serial_write_fifo(dev->serial, 0x06); -#ifndef __APPLE__ - [[fallthrough]]; -#endif - 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); - break; - case PHASE_FORMAT_AND_REVISION: - serial_write_fifo(dev->serial, 0x10 | (dev->format << 1)); - sermouse_command_phase_idle(dev); - break; - case PHASE_BUTTONS: - serial_write_fifo(dev->serial, dev->but); - sermouse_command_phase_idle(dev); - break; - default: - sermouse_command_phase_idle(dev); - break; - } -} - -static int -sermouse_poll(int x, int y, int z, int b, UNUSED(double abs_x), UNUSED(double abs_y), void *priv) -{ - mouse_t *dev = (mouse_t *) priv; - - if (!x && !y && !z && (b == dev->oldb)) { - dev->oldb = b; - return 1; - } - - 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; - } - - dev->rel_x += x; - dev->rel_y += y; - dev->rel_z += z; - - return 0; -} - -static void -ltsermouse_prompt_mode(mouse_t *dev, int prompt) -{ - dev->prompt = prompt; - dev->status &= 0xBF; - if (prompt) - dev->status |= 0x40; -} - -static void -ltsermouse_command_phase(mouse_t *dev, int phase) -{ - dev->command_pos = 0; - dev->command_phase = phase; - timer_stop(&dev->command_timer); - sermouse_timer_on(dev, dev->transmit_period, 0); -} - -static void -ltsermouse_set_report_period(mouse_t *dev, int rps) -{ - 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; -} - -static void -ltsermouse_switch_baud_rate(mouse_t *dev, int phase) -{ - dev->command_pos = 0; - dev->command_phase = phase; - timer_stop(&dev->command_timer); - sermouse_timer_on(dev, 10000.0, 0); -} - -static void -ltsermouse_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) -{ - 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); -#ifndef __APPLE__ - [[fallthrough]]; -#endif - 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; - default: - 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; - - default: - break; - } + memcpy(dev->buf, dev->id, dev->id_len); + sermouse_transmit(dev, dev->id_len, 0, 0); } static void @@ -762,7 +811,7 @@ ltsermouse_transmit_period(UNUSED(serial_t *serial), void *priv, double transmit { mouse_t *dev = (mouse_t *) priv; - dev->auto_period = transmit_period; + dev->host_transmit_period = transmit_period; } static void @@ -770,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 @@ -801,26 +840,36 @@ 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) { default: case 2: @@ -840,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; } +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 { @@ -944,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 }; @@ -959,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 32856634e..d299d8bab 100644 --- a/src/device/mouse_wacom_tablet.c +++ b/src/device/mouse_wacom_tablet.c @@ -215,7 +215,7 @@ wacom_process_settings_dword(mouse_wacom_t *wacom, uint32_t dword) break; } - mouse_mode = !wacom->settings_bits.coord_sys; + mouse_input_mode = !wacom->settings_bits.coord_sys; wacom->x_res = wacom->y_res = wacom_resolution_values[wacom->settings_bits.resolution]; } @@ -235,7 +235,7 @@ wacom_reset(mouse_wacom_t *wacom) wacom->settings_bits.remote_mode = wacom->remote_req = 0; wacom->settings_bits.out_of_range_data = 0; - mouse_mode = 1; + mouse_input_mode = 1; wacom_process_settings_dword(wacom, 0xA21BC800); } @@ -257,7 +257,7 @@ wacom_reset_artpad(mouse_wacom_t *wacom) wacom->settings_bits.out_of_range_data = 0; wacom_process_settings_dword(wacom, 0xE203C000); - mouse_mode = 1; + mouse_input_mode = 1; } static void @@ -364,8 +364,8 @@ wacom_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) } else if (!memcmp(wacom->data_rec, "IT", 2)) { sscanf((const char *) wacom->data_rec, "IT%d", &wacom->interval); } else if (!memcmp(wacom->data_rec, "DE", 2) && wacom->settings_bits.cmd_set == WACOM_CMDSET_IIS) { - sscanf((const char *) wacom->data_rec, "DE%d", &mouse_mode); - mouse_mode = !mouse_mode; + sscanf((const char *) wacom->data_rec, "DE%d", &mouse_input_mode); + mouse_input_mode = !mouse_input_mode; plat_mouse_capture(0); } else if (!memcmp(wacom->data_rec, "SU", 2)) { sscanf((const char *) wacom->data_rec, "SU%d", &wacom->suppressed_increment); @@ -424,9 +424,17 @@ wacom_write(UNUSED(struct serial_s *serial), void *priv, uint8_t data) } static int -wacom_poll(int x, int y, UNUSED(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.); @@ -442,8 +450,8 @@ wacom_poll(int x, int y, UNUSED(int z), int b, double abs_x, double abs_y, void 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; @@ -512,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; } @@ -555,7 +563,7 @@ wacom_report_timer(void *priv) { mouse_wacom_t *wacom = (mouse_wacom_t *) priv; double milisecond_diff = ((double) (tsc - wacom->old_tsc)) / cpuclock * 1000.0; - int relative_mode = (mouse_mode == 0); + int relative_mode = (mouse_input_mode == 0); int x = (relative_mode ? wacom->rel_x : wacom->abs_x); int y = (relative_mode ? wacom->rel_y : wacom->abs_y); int x_diff = abs(relative_mode ? wacom->rel_x : (wacom->abs_x - wacom->last_abs_x)); diff --git a/src/device/nec_mate_unk.c b/src/device/nec_mate_unk.c new file mode 100644 index 000000000..165962f30 --- /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 eb0c734aa..8183f8afa 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -54,7 +54,7 @@ typedef struct pci_bridge_t { uint8_t regs[256]; uint8_t bus_index; - int slot; + uint8_t slot; } pci_bridge_t; #ifdef ENABLE_PCI_BRIDGE_LOG @@ -493,7 +493,7 @@ 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; @@ -501,7 +501,9 @@ pci_bridge_init(const device_t *info) for (uint8_t i = 0; i < interrupt_count; i++) interrupts[i] = pci_get_int(dev->slot, PCI_INTA + i); } - pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0], interrupts[1], interrupts[2], interrupts[3]); + pci_bridge_log("PCI Bridge %d: upstream bus %02X slot %02X interrupts %02X %02X %02X %02X\n", + dev->bus_index, (dev->slot >> 5) & 0xff, dev->slot & 31, interrupts[0], + interrupts[1], interrupts[2], interrupts[3]); if (info->local == PCI_BRIDGE_DEC_21150) slot_count = 9; /* 9 bus masters */ @@ -510,7 +512,10 @@ pci_bridge_init(const device_t *info) for (uint8_t i = 0; i < slot_count; i++) { /* Interrupts for bridge slots are assigned in round-robin: ABCD, BCDA, CDAB and so on. */ - pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n", dev->bus_index, i, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], interrupts[(i + 3) & interrupt_mask]); + pci_bridge_log("PCI Bridge %d: downstream slot %02X interrupts %02X %02X %02X %02X\n", + dev->bus_index, i, interrupts[i & interrupt_mask], + interrupts[(i + 1) & interrupt_mask], interrupts[(i + 2) & interrupt_mask], + interrupts[(i + 3) & interrupt_mask]); pci_register_bus_slot(dev->bus_index, i, AGP_BRIDGE(dev->local) ? PCI_CARD_AGP : PCI_CARD_NORMAL, interrupts[i & interrupt_mask], interrupts[(i + 1) & interrupt_mask], diff --git a/src/device/phoenix_486_jumper.c b/src/device/phoenix_486_jumper.c index dbdfbe946..a3c891c90 100644 --- a/src/device/phoenix_486_jumper.c +++ b/src/device/phoenix_486_jumper.c @@ -6,15 +6,16 @@ * * This file is part of the 86Box distribution. * - * Implementation of the Phoenix 486 Jumper Readout + * Implementation of the Phoenix 486 Jumper Readout. * * * - * Authors: Tiseno100 + * Authors: Miran Grca, + * Tiseno100, * - * Copyright 2020 Tiseno100 + * Copyright 2020-2023 Miran Grca. + * Copyright 2020-2023 Tiseno100. */ - #include #include #include diff --git a/src/device/postcard.c b/src/device/postcard.c index f5e85dafb..dbae3232a 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,22 +117,25 @@ 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(UNUSED(uint16_t port), uint8_t val, UNUSED(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(); } @@ -102,7 +143,7 @@ postcard_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) static void * 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(UNUSED(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 a36e4f99f..37aadf8fe 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; + /* 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 = 1; + dev->iir = (dev->iir & 0xf0) | 0x01; - 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; + 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,60 +159,48 @@ serial_receive_timer(void *priv) { serial_t *dev = (serial_t *) priv; -#if 0 serial_log("serial_receive_timer()\n"); -#endif 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); + fifo_write_evt((uint8_t) (dev->out_new & 0xff), dev->rcvr_fifo); + dev->out_new = 0xffff; + #if 0 - dev->rcvr_fifo_end = (dev->rcvr_fifo_end + 1) & 0x0f; + pclog("serial_receive_timer(): lsr = %02X, ier = %02X, iir = %02X, int_status = %02X\n", + dev->lsr, dev->ier, dev->iir, dev->int_status); #endif - /* 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; + 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); - 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); - } + /* Indicate overrun. */ + if (dev->lsr & 0x01) + dev->lsr |= 0x02; - /* Now wrap around. */ - dev->rcvr_fifo_end &= 0x0f; + dev->dat = (uint8_t) (dev->out_new & 0xff); + dev->out_new = 0xffff; - if (dev->rcvr_fifo_end == dev->rcvr_fifo_pos) - dev->rcvr_fifo_full = 1; + /* Raise Data Ready interrupt. */ + dev->lsr |= 0x01; + dev->int_status |= SERIAL_INT_RECEIVE; - timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); - } + serial_update_ints(dev); } } - - serial_update_ints(dev); } static void @@ -215,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; @@ -243,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); @@ -256,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. */ } @@ -308,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); } @@ -361,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; @@ -375,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; @@ -389,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 @@ -475,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); @@ -495,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: @@ -530,42 +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: @@ -591,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; @@ -615,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: @@ -651,9 +624,9 @@ serial_write(uint16_t addr, uint8_t val, void *p) } 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); @@ -665,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; @@ -707,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) @@ -750,7 +698,6 @@ serial_read(uint16_t addr, void *p) 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; } @@ -792,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]; @@ -843,6 +809,9 @@ serial_close(void *priv) next_inst--; + if (com_ports[dev->inst].enabled) + fifo_close(dev->rcvr_fifo); + free(dev); } @@ -851,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 * @@ -888,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) @@ -910,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++; diff --git a/src/device/serial_passthrough.c b/src/device/serial_passthrough.c index b703cd67c..1b1c5e3bf 100644 --- a/src/device/serial_passthrough.c +++ b/src/device/serial_passthrough.c @@ -25,6 +25,7 @@ #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> @@ -78,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 { diff --git a/src/device/smbus_ali7101.c b/src/device/smbus_ali7101.c index 1e1e61c52..349de470d 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; @@ -192,10 +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 */ - -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; default: /* unknown */ dev->next_stat = 0x20; /* raise DEV_ERR */ diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index 03a465f1c..6f2b1632e 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; @@ -194,10 +195,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) i2c_write(i2c_smbus, smbus_addr, dev->cmd); timer_bytes++; } - -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0xc: /* I2C process call */ if (!read) { /* word write (only when writing) */ @@ -215,10 +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 */ - -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0xd: /* I2C block R/W */ i2c_write(i2c_smbus, smbus_addr, dev->cmd); @@ -250,10 +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++; - -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0xe: /* I2C with 7-bit address */ if (!read) { /* word write (only when writing) */ diff --git a/src/device/unittester.c b/src/device/unittester.c new file mode 100644 index 000000000..e52f3b56f --- /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 7771a0b72..00da385d4 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) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc.c b/src/disk/hdc.c index f1ef1ecf6..07df9d0e6 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> @@ -142,7 +143,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 +155,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 1aa18bd62..65184094a 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -338,9 +338,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) esdi->command &= ~0x03; if (val & 0x02) fatal("Read with ECC\n"); -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0xa0: esdi->status = STAT_BUSY; @@ -399,9 +397,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv) default: esdi_at_log("WD1007: bad command %02X\n", val); -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0xe8: /*???*/ esdi->status = STAT_BUSY; esdi_set_callback(esdi, 200 * HDC_TIME); @@ -793,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; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index dfc308590..299c5c487 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,73 +110,118 @@ #define IDE_TIME 10.0 +#define IDE_ATAPI_IS_EARLY ide->sc->pad0 + +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; + 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; - uint16_t base_main; - uint16_t side_main; + pc_timer_t timer; + ide_t *ide[2]; + ide_bm_t *bm; } ide_board_t; -typedef struct ide_bm_t { - int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv); - void (*set_irq)(int channel, void *priv); - 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 }; +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 */ + /* 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', - 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 */ + /* 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, - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + /* 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 */ + /* 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', - 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 */ + /* 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, - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + /* End tag, dummy checksum (filled in by isapnp_add_card) */ + 0x79, 0x00 }; ide_t *ide_drives[IDE_NUM]; @@ -207,7 +252,7 @@ ide_log(const char *fmt, ...) uint8_t getstat(ide_t *ide) { - return ide->atastat; + return ide->tf->atastat; } ide_t * @@ -330,71 +375,46 @@ ide_atapi_get_period(uint8_t channel) return ide_get_xfer_time(ide, 1); } -void -ide_irq_raise(ide_t *ide) -{ - if (!ide_boards[ide->board]) - return; - - /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - - ide_log("IDE %i: IRQ raise\n", ide->board); - - 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->irqstat = 1; - ide->service = 1; -} - -void -ide_irq_lower(ide_t *ide) -{ - 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; -} - static void -ide_irq_update(ide_t *ide) +ide_irq_update(ide_board_t *dev, int log) +{ + ide_t *ide; + uint8_t set; + + if (dev == NULL) + return; + +#ifdef ENABLE_IDE_LOG + if (log) + ide_log("IDE %i: IRQ update (%i)\n", dev->cur_dev >> 1, dev->irq); +#endif + + ide = ide_drives[dev->cur_dev]; + set = !(ide_boards[ide->board]->devctl & 2) && ide->irqstat; + + 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(ide_t *ide, int set, int log) { if (!ide_boards[ide->board]) return; - /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("IDE %i: IRQ %s\n", ide->channel, set ? "raise" : "lower"); +#endif - 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); - } + ide->irqstat = set; + + if (set) + ide->service = 1; + + if (ide->selected) + ide_irq_update(ide_boards[ide->board], log); } /** @@ -443,59 +463,37 @@ ide_padstr8(uint8_t *buf, int buf_size, const char *src) static int ide_get_max(ide_t *ide, int type) { + 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 } }; + if (ide->type == IDE_ATAPI) - return ide->get_max(!ide->sc->pad0 && !ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type); + 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); - 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; - - 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; - - return -1; - default: - fatal("Unknown transfer type: %i\n", type); - return -1; - } + return ret; } static int ide_get_timings(ide_t *ide, int type) { + 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 } }; + if (ide->type == IDE_ATAPI) - return ide->get_timings(!ide->sc->pad0 && !ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL), type); + 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); - switch (type) { - case TIMINGS_DMA: - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 120; - - return 0; - case TIMINGS_PIO: - if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 120; - - return 0; - case TIMINGS_PIO_FC: - return 0; - default: - fatal("Unknown transfer type: %i\n", type); - return 0; - } + return ret; } /** @@ -505,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; @@ -538,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)) { @@ -556,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) { @@ -577,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 { @@ -604,14 +615,15 @@ ide_identify(ide_t *ide) 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"); @@ -668,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); } @@ -702,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; } } @@ -720,16 +734,16 @@ ide_get_sector(ide_t *ide) static void ide_next_sector(ide_t *ide) { - if (ide->lba) + 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++; + ide->tf->sector++; + if ((ide->tf->sector == 0) || (ide->tf->sector == (ide->cfg_spt + 1))) { + ide->tf->sector = 1; + ide->tf->head++; + if ((ide->tf->head == 0) || (ide->head == ide->cfg_hpc)) { + ide->tf->head = 0; + ide->tf->cylinder++; } } } @@ -755,23 +769,15 @@ loadhd(ide_t *ide, int d, UNUSED(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; -#if 0 - ide->cylinder = ((ide->type == IDE_HDD) ? 0 : 0xFFFF); -#endif - 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 @@ -783,10 +789,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); @@ -803,7 +807,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 */ @@ -811,7 +816,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 */ @@ -819,7 +825,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 */ @@ -827,7 +834,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 */ @@ -835,7 +843,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: @@ -869,16 +878,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; } } @@ -886,14 +895,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); @@ -905,31 +916,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; @@ -964,9 +975,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); } @@ -976,90 +987,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) { + 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 + + switch (ide->sc->packet_status) { + default: + break; + case PHASE_IDLE: -#ifdef ENABLE_IDE_LOG - ide_log("PHASE_IDLE\n"); -#endif - ide->sc->pos = 0; - ide->sc->phase = 1; - ide->sc->status = READY_STAT | DRQ_STAT | (ide->sc->status & ERR_STAT); - return; + 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); + 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); - } 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; + 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; } } @@ -1069,14 +1081,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) @@ -1085,23 +1097,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); @@ -1109,168 +1121,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; - const uint16_t *bufferw; - const uint32_t *bufferl; + uint16_t ret = 0; - uint32_t temp = 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); - if (!dev || !dev->temp_buffer || (dev->packet_status != PHASE_DATA_IN)) - return 0; + bufferw = (uint16_t *) dev->temp_buffer; - 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; + /* 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; + uint8_t *bufferb = NULL; + uint16_t *bufferw = NULL; - if (!dev) - return; - - 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; } - 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; + 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; - break; - case 4: - bufferl[dev->pos >> 2] = val; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return; - } + } else { + bufferb[ide->tf->pos] = val & 0xff; + ide->tf->pos++; + dev->request_pos++; + } - 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 (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; - } 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); - } - 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); } } } @@ -1279,7 +1246,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; @@ -1287,7 +1254,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; @@ -1319,7 +1288,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; @@ -1368,14 +1339,14 @@ ide_write_devctl(UNUSED(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; @@ -1386,44 +1357,28 @@ ide_write_devctl(UNUSED(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; @@ -1434,12 +1389,15 @@ ide_write_devctl(UNUSED(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; @@ -1451,111 +1409,124 @@ ide_write_devctl(UNUSED(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)) + if ((old ^ val) & 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_other->type == IDE_ATAPI) { - ide_log("Other sector count write: %i\n", val); - ide_other->sc->phase = val; - } - ide_other->secount = val; - return; + 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; 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->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->sector = val; + ide->lba_addr = (ide->lba_addr & 0xfffff00) | val; + } + + 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; - } - ide->cylinder = (ide->cylinder & 0xFF00) | val; - ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); + if (ide->type & IDE_SHADOW) + break; - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->request_length &= 0xFF00; - ide_other->sc->request_length |= val; + 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_other->cylinder = (ide_other->cylinder & 0xFF00) | val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFF00FF) | (val << 8); - return; + + 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); + } + break; case 0x5: /* Cylinder high */ - if (ide->type == IDE_ATAPI) { - ide->sc->request_length &= 0xFF; - ide->sc->request_length |= (val << 8); - } - ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); - ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); + if (ide->type & IDE_SHADOW) + break; - if (ide_other->type == IDE_ATAPI) { - ide_other->sc->request_length &= 0xFF; - ide_other->sc->request_length |= (val << 8); + 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_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); - ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); - return; + + 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); + } + 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; @@ -1566,87 +1537,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; + ide_reset_registers(ide); + ide_reset_registers(ide_other); - 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_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; + 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->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); - ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 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; - - 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; - - 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; - } + ide->tf->error = 0; 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], (val & 0x60) ? + ide_get_sector(ide) : 0, HDD_OP_SEEK, 0, 0.0); + ide_set_callback(ide, seek_time); + } + break; + 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: @@ -1655,42 +1608,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; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + 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; } @@ -1698,7 +1651,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. */ @@ -1706,20 +1659,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); -#ifndef __APPLE__ - [[fallthrough]]; -#endif + 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: @@ -1728,46 +1674,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; @@ -1778,21 +1725,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; @@ -1800,51 +1739,45 @@ 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; @@ -1853,150 +1786,131 @@ ide_bad_command: } } -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; - const uint32_t *idebufferl = (uint32_t *) ide->buffer; + uint16_t ret = 0; + double seek_us; + double xfer_us; - if (ide->command == WIN_PACKETCMD) { - ide->pos = 0; +#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->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 (length == 2) { + ret = idebufferw[ide->tf->pos >> 1]; + ide->tf->pos += 2; + } else { + ret = idebufferb[ide->tf->pos]; + ide->tf->pos++; } - } - 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 ((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) { 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: @@ -2013,75 +1927,67 @@ 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(UNUSED(uint16_t addr), void *priv) { - uint8_t temp = 0xff; + uint8_t ret = 0xff; const ide_board_t *dev = (ide_board_t *) priv; @@ -2093,16 +1999,16 @@ ide_read_alt_status(UNUSED(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; const ide_board_t *dev = (ide_board_t *) priv; @@ -2114,86 +2020,84 @@ 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; - - const 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 - - 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->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; - } + ide_log("ide_board_callback(%i)\n", dev->cur_dev >> 1); dev->cur_dev &= ~1; + /* 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; + } + + 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); } } @@ -2201,15 +2105,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); } @@ -2218,151 +2117,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_SRST: /*ATAPI Device Reset */ + 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; - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; /*Device passed*/ - ide->secount = 1; - ide->sector = 1; + 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->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; + 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); + + ide->sector_pos++; + + ide->tf->pos = 0; + ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + + ide_irq_raise(ide); + + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); } - 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); - } - - memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); - - ide->sector_pos++; - ide->pos = 0; - - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - - ide_irq_raise(ide); - - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; + 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); - } else { - /* Bus master DMAS error, abort the command. */ - ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); - goto abort_cmd; - } + err = IDNF_ERR; } else { - ide_log("IDE %i: DMA read aborted (no bus master)\n", ide->channel); - goto abort_cmd; + 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 { + ide_log("IDE %i: DMA read aborted (no bus master)\n", ide->channel); + err = ABRT_ERR; + } } - return; + break; case WIN_READ_MULTIPLE: /* According to the official ATA reference: @@ -2372,99 +2271,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; + 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); + } - 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); + memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); + + ide->sector_pos++; + ide->tf->pos = 0; + + 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; } - - memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); - - ide->sector_pos++; - ide->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; + 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; - - ret = ide_bm[ide->board]->dma(ide->board, - ide->sector_buffer, ide->sector_pos * 512, - 1, 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 write successful\n", ide->channel); - - hdd_image_write(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); - - ide->atastat = DRDY_STAT | DSC_STAT; - - 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); - goto abort_cmd; - } + err = IDNF_ERR; } else { - ide_log("IDE %i: DMA write aborted (no bus master)\n", ide->channel); - goto abort_cmd; - } + 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; - return; + 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->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); + + 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 DMA error, abort the command. */ + ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); + err = ABRT_ERR; + } + } else { + ide_log("IDE %i: DMA write aborted (no bus master)\n", ide->channel); + err = ABRT_ERR; + } + } + break; case WIN_WRITE_MULTIPLE: /* According to the official ATA reference: @@ -2474,157 +2375,155 @@ 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); + 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); + } } - 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); - } - 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; - - 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; - - case WIN_IDENTIFY: /* Identify Device */ - if (ide->type != IDE_HDD) { - ide_set_signature(ide); - goto abort_cmd; - } else { - ide_identify(ide); - ide->pos = 0; - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; ide_irq_raise(ide); } - return; + break; + + case WIN_READ_NATIVE_MAX: + 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_identify(ide); + 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; + } + break; case WIN_PACKETCMD: /* ATAPI Packet */ - if (ide->type != IDE_ATAPI) - goto abort_cmd; - - ide_atapi_callback(ide); - return; - - case 0xFF: - goto abort_cmd; + if (ide->type == IDE_ATAPI) + ide_atapi_callback(ide); + else + err = ABRT_ERR; + break; 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 @@ -2667,130 +2566,74 @@ ide_read_ali_76(void) 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) +ide_handlers(uint8_t board, int set) { - if (ide_boards[board] == NULL) - return; + 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]->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]); + 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_remove_handlers(uint8_t board) +ide_set_base_addr(int board, int base, uint16_t port) { - if (ide_boards[board] == NULL) - return; + ide_log("ide_set_base_addr(%i, %i, %04X)\n", board, base, port); - 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]); - } - - 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]); - } -} - -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_log("ide_set_side(%i, %04X)\n", board, port); - - if (ide_boards[board] == NULL) - return; - - 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 @@ -2818,28 +2661,31 @@ ide_board_close(int board) dev = ide_drives[c]; - if (dev == NULL) - continue; + if (dev != NULL) { + if ((dev->type == IDE_HDD) && (dev->hdd_num != -1)) + hdd_image_close(dev->hdd_num); - if ((dev->type == IDE_HDD) && (dev->hdd_num != -1)) - hdd_image_close(dev->hdd_num); + 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->type == IDE_ATAPI) - dev->sc->status = DRDY_STAT | DSC_STAT; + 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; + } } } @@ -2883,8 +2729,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; } @@ -2903,7 +2748,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) @@ -2921,14 +2766,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); @@ -2946,18 +2792,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) @@ -2981,9 +2829,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]); @@ -3012,10 +2861,10 @@ 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]); } @@ -3043,15 +2892,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 * @@ -3060,12 +2914,7 @@ 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) @@ -3076,7 +2925,7 @@ ide_init(const device_t *info) break; } - return ide_drives; + return (void *) (intptr_t) -1; } static void @@ -3084,11 +2933,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]) { @@ -3122,17 +2977,32 @@ 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(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. */ @@ -3141,14 +3011,11 @@ 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; + } } } @@ -3243,7 +3110,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 = { @@ -3269,7 +3136,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 000000000..eee3844c4 --- /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 6cb54aea5..3e77730a2 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -42,9 +42,12 @@ typedef struct cmd640_t { uint8_t id; uint8_t in_cfg; uint8_t channels; - uint8_t pci, regs[256]; + uint8_t pci; + uint8_t irq_state; + uint8_t pci_slot; + uint8_t pad0; + uint8_t regs[256]; uint32_t local; - int slot; int irq_mode[2]; int irq_pin; int irq_line; @@ -71,38 +74,52 @@ cmd640_log(const char *fmt, ...) #endif void -cmd640_set_irq(int channel, void *priv) +cmd640_set_irq_0(uint8_t status, void *priv) { cmd640_t *dev = (cmd640_t *) priv; - int irq = !!(channel & 0x40); + int irq = !!(status & 0x04); - if (channel & 0x01) { - if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { - dev->regs[0x57] &= ~0x10; - dev->regs[0x57] |= (channel >> 2); - } - } else { - if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); - } - } + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; - channel &= 0x01; - - if (!(dev->channels & (1 << channel))) + if (!(dev->channels & 1)) return; if (irq) { - if (dev->irq_mode[channel] == 1) - pci_set_irq(dev->slot, dev->irq_pin); + if (dev->irq_mode[0] == 1) + pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); else - picint(1 << (14 + channel)); + picint(1 << 14); } else { - if (dev->irq_mode[channel] == 1) - pci_clear_irq(dev->slot, dev->irq_pin); + if (dev->irq_mode[0] == 1) + pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); else - picintc(1 << (14 + channel)); + picintc(1 << 14); + } +} + +void +cmd640_set_irq_1(uint8_t status, void *priv) +{ + cmd640_t *dev = (cmd640_t *) priv; + int irq = !!(status & 0x04); + + if (!(dev->regs[0x57] & 0x10) || (status & 0x04)) + dev->regs[0x57] = (dev->regs[0x57] & ~0x10) | (status << 2); + + if (!(dev->channels & 2)) + return; + + if (irq) { + if (dev->irq_mode[1] == 1) + pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); + else + picint(1 << 15); + } else { + if (dev->irq_mode[1] == 1) + pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); + else + picintc(1 << 15); } } @@ -412,10 +429,10 @@ cmd640_reset(void *priv) } if (dev->channels & 0x01) - cmd640_set_irq(0x00, priv); + cmd640_set_irq_0(0x00, priv); if (dev->channels & 0x02) - cmd640_set_irq(0x01, priv); + cmd640_set_irq_1(0x00, priv); memset(dev->regs, 0x00, sizeof(dev->regs)); @@ -500,13 +517,16 @@ cmd640_init(const device_t *info) 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); if (dev->channels & 0x01) - ide_set_bus_master(0, NULL, cmd640_set_irq, dev); + ide_set_bus_master(0, NULL, cmd640_set_irq_0, dev); if (dev->channels & 0x02) - ide_set_bus_master(1, NULL, cmd640_set_irq, dev); + ide_set_bus_master(1, NULL, cmd640_set_irq_1, dev); /* The CMD PCI-0640B IDE controller has no DMA capability, so set our devices IDE devices to force ATA-3 (no DMA). */ diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index 1f727bf6b..8367b9a41 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -41,11 +41,16 @@ 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 slot; - int irq_mode[2]; + int irq_pin; + + int irq_mode[2]; + sff8038i_t *bm[2]; } cmd646_t; @@ -68,31 +73,41 @@ cmd646_log(const char *fmt, ...) #endif static void -cmd646_set_irq(int channel, void *priv) +cmd646_set_irq_0(uint8_t status, void *priv) { cmd646_t *dev = (cmd646_t *) priv; - if (channel & 0x01) { - if (!(dev->regs[0x57] & 0x10) || (channel & 0x40)) { - dev->regs[0x57] &= ~0x10; - dev->regs[0x57] |= (channel >> 2); - } - } else { - if (!(dev->regs[0x50] & 0x04) || (channel & 0x40)) { - dev->regs[0x50] &= ~0x04; - dev->regs[0x50] |= (channel >> 4); - } - } + if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) + dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; - sff_bus_master_set_irq(channel, dev->bm[channel & 0x01]); + sff_bus_master_set_irq(status, dev->bm[0]); +} + +static void +cmd646_set_irq_1(uint8_t status, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + + if (!(dev->regs[0x57] & 0x10) || (status & 0x04)) + dev->regs[0x57] = (dev->regs[0x57] & ~0x10) | (status << 2); + + sff_bus_master_set_irq(status, dev->bm[1]); } static int -cmd646_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv) +cmd646_bus_master_dma_0(uint8_t *data, int transfer_length, int out, void *priv) { const cmd646_t *dev = (cmd646_t *) priv; - return sff_bus_master_dma(channel, data, transfer_length, out, dev->bm[channel & 0x01]); + return sff_bus_master_dma(data, transfer_length, out, dev->bm[0]); +} + +static int +cmd646_bus_master_dma_1(uint8_t *data, int transfer_length, int out, void *priv) +{ + const cmd646_t *dev = (cmd646_t *) priv; + + return sff_bus_master_dma(data, transfer_length, out, dev->bm[1]); } static void @@ -100,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(); @@ -116,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(); @@ -143,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(); @@ -313,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)); @@ -382,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); @@ -390,17 +409,14 @@ cmd646_init(const device_t *info) if (!dev->single_channel) dev->bm[1] = device_add_inst(&sff8038i_device, 2); - ide_set_bus_master(0, cmd646_bus_master_dma, cmd646_set_irq, dev); + ide_set_bus_master(0, cmd646_bus_master_dma_0, cmd646_set_irq_0, dev); if (!dev->single_channel) - ide_set_bus_master(1, cmd646_bus_master_dma, cmd646_set_irq, dev); + ide_set_bus_master(1, cmd646_bus_master_dma_1, cmd646_set_irq_1, dev); - sff_set_irq_mode(dev->bm[0], 0, 0); - sff_set_irq_mode(dev->bm[0], 1, 0); + sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); - if (!dev->single_channel) { - sff_set_irq_mode(dev->bm[1], 0, 0); - sff_set_irq_mode(dev->bm[1], 1, 0); - } + if (!dev->single_channel) + sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); cmd646_reset(dev); diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 5e8e4e987..3f43f80e6 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> @@ -74,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, @@ -314,7 +316,7 @@ sff_bus_master_readl(uint16_t port, void *priv) } int -sff_bus_master_dma(UNUSED(int channel), uint8_t *data, int transfer_length, int out, void *priv) +sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; #ifdef ENABLE_SFF_LOG @@ -385,64 +387,67 @@ sff_bus_master_dma(UNUSED(int channel), uint8_t *data, int transfer_length, int } void -sff_bus_master_set_irq(int channel, void *priv) +sff_bus_master_set_irq(uint8_t status, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; - uint8_t irq = !!(channel & 0x40); + uint8_t irq = !!(status & 0x04); - if (!(dev->status & 0x04) || (channel & 0x40)) { - dev->status &= ~0x04; - dev->status |= (channel >> 4); - } + if (!(dev->status & 0x04) || (status & 0x04)) + dev->status = (dev->status & ~0x04) | status; - channel &= 0x01; - - switch (dev->irq_mode[channel]) { + switch (dev->irq_mode) { default: - case 0: + case IRQ_MODE_LEGACY: /* Legacy IRQ mode. */ if (irq) - picint(1 << (14 + channel)); - else - picintc(1 << (14 + channel)); - break; - case 1: - /* Native PCI IRQ mode with interrupt pin. */ - if (irq) - pci_set_irq(dev->slot, dev->irq_pin); - else - pci_clear_irq(dev->slot, dev->irq_pin); - break; - case 2: - case 5: - /* MIRQ 0 or 1. */ - if (irq) - pci_set_mirq(dev->irq_mode[channel] & 1, 0); - else - pci_clear_mirq(dev->irq_mode[channel] & 1, 0); - break; - case 3: - /* Native PCI IRQ mode with specified interrupt line. */ - if (irq) - picintlevel(1 << dev->irq_line); + picint(1 << dev->irq_line); else picintc(1 << dev->irq_line); break; - case 4: + case IRQ_MODE_PCI_IRQ_PIN: + /* Native PCI IRQ mode with interrupt pin. */ + if (irq) + pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state); + else + pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); + break; + case IRQ_MODE_MIRQ_0 ... IRQ_MODE_MIRQ_3: + /* MIRQ 0, 1, 2, or 3. */ + if (irq) + pci_set_mirq(dev->irq_mode & 3, 0, &dev->irq_state); + else + pci_clear_mirq(dev->irq_mode & 3, 0, &dev->irq_state); + break; + /* TODO: Redo this as a MIRQ. */ + case IRQ_MODE_PCI_IRQ_LINE: + /* Native PCI IRQ mode with specified interrupt line. */ + if (irq) + pci_set_dirq(dev->pci_irq_line, &dev->irq_state); + else + pci_clear_dirq(dev->pci_irq_line, &dev->irq_state); + break; + 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(2, 1, &dev->irq_state); + else + pci_clear_mirq(2, 1, &dev->irq_state); break; } } void -sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base) +sff_bus_master_reset(sff8038i_t *dev) { - if (dev->enabled) { - io_removehandler(old_base, 0x08, + if (dev->enabled && (dev->base != 0x0000)) { + io_removehandler(dev->base, 0x08, sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, dev); @@ -456,6 +461,7 @@ 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(); @@ -468,6 +474,10 @@ sff_reset(void *priv) sff_log("SFF8038i: Reset\n"); #endif + 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); @@ -492,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, UNUSED(int irq_level)) +{ + dev->irq_level = 0; } void -sff_set_irq_level(sff8038i_t *dev, int channel, UNUSED(int irq_level)) +sff_set_irq_mode(sff8038i_t *dev, int irq_mode) { - dev->irq_level[channel] = 0; -} + dev->irq_mode = irq_mode; -void -sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode) -{ - dev->irq_mode[channel] = irq_mode; - - switch (dev->irq_mode[channel]) { + switch (dev->irq_mode) { default: - case 0: + case IRQ_MODE_LEGACY: /* Legacy IRQ mode. */ - sff_log("[%08X] Setting channel %i to legacy IRQ %i\n", dev, channel, 14 + channel); + sff_log("[%08X] Setting IRQ mode to legacy IRQ %i\n", dev, 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; } } @@ -565,12 +579,15 @@ sff_init(UNUSED(const device_t *info)) ide_set_bus_master(next_id, sff_bus_master_dma, sff_bus_master_set_irq, dev); dev->slot = 7; - dev->irq_mode[0] = 0; /* Channel 0 goes to IRQ 14. */ - dev->irq_mode[1] = 2; /* Channel 1 goes to MIRQ0. */ + /* Channel 0 goes to IRQ 14, channel 1 goes to MIRQ0. */ + dev->irq_mode = next_id ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY; dev->irq_pin = PCI_INTA; - dev->irq_line = 14; - dev->irq_level[0] = dev->irq_level[1] = 0; + dev->irq_line = 14 + next_id; + dev->pci_irq_line = 14; + dev->irq_level = 0; + dev->irq_state = 0; + dev->channel = next_id; next_id++; return dev; diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 0843a35ee..79a5a8eba 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -623,10 +623,7 @@ st506_callback(void *priv) st506_complete(dev); break; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif - + fallthrough; case CMD_FORMAT_TRACK: case CMD_FORMAT_BAD_TRACK: switch (dev->state) { @@ -673,6 +670,7 @@ st506_callback(void *priv) st506_complete(dev); break; } + fallthrough; case CMD_READ: #if 0 case CMD_READ_LONG: @@ -772,6 +770,7 @@ st506_callback(void *priv) st506_complete(dev); break; } + fallthrough; case CMD_WRITE: #if 0 case CMD_WRITE_LONG: @@ -1534,6 +1533,7 @@ static void set_switches(hdc_t *dev, hd_type_t *hdt, int num) { const drive_t *drive; + int c; int e; dev->switches = 0x00; @@ -1547,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 @@ -1575,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)); @@ -1608,9 +1608,7 @@ st506_init(const device_t *info) case ST506_XT_TYPE_ST11R: /* Seagate ST-11R (RLL) */ dev->spt = RLL_SECTORS; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case ST506_XT_TYPE_ST11M: /* Seagate ST-11M (MFM) */ dev->nr_err = ERR_NOT_AVAILABLE; diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index d5cf829ba..ede21caf2 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" @@ -248,7 +248,6 @@ typedef struct hdc_t { 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. */ @@ -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) @@ -449,16 +432,13 @@ do_fmt: 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; @@ -509,9 +489,7 @@ hdc_callback(void *priv) case CMD_READ_VERIFY: no_data = 1; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case CMD_READ_SECTORS: if (!drive->present) { @@ -536,9 +514,7 @@ hdc_callback(void *priv) dev->buf_len = 512; dev->state = STATE_SEND; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case STATE_SEND: /* Activate the status icon. */ @@ -562,12 +538,12 @@ do_send: 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, @@ -590,14 +566,14 @@ do_send: 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; @@ -646,9 +622,7 @@ do_send: dev->buf_len = 512; dev->state = STATE_RECV; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case STATE_RECV: /* Activate the status icon. */ @@ -660,7 +634,7 @@ do_recv: 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; @@ -679,7 +653,7 @@ do_recv: 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; } @@ -687,7 +661,7 @@ do_recv: dev->buf_idx++; } dev->state = STATE_RDONE; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } break; @@ -791,7 +765,7 @@ do_recv: 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; @@ -806,7 +780,7 @@ do_recv: 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; } @@ -814,7 +788,7 @@ do_recv: dev->buf_idx++; } dev->state = STATE_RDONE; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } break; @@ -834,7 +808,7 @@ do_recv: 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: @@ -851,7 +825,7 @@ do_recv: 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; @@ -872,7 +846,7 @@ do_recv: 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: @@ -917,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); @@ -975,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; @@ -1009,12 +983,12 @@ hdc_write(uint16_t port, uint8_t val, void *priv) 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)); @@ -1030,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; diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index 91bf5a2e3..dfe5931f1 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -40,6 +40,7 @@ #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> diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 685eec9d0..3bb15c241 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -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++; } diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 4d3e354f2..df473d7d9 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -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 @@ retry_vhd: 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; diff --git a/src/disk/minivhd/create.c b/src/disk/minivhd/create.c index ebfbb69a2..d06382ef9 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 053acc40c..7ac3989e6 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 02ef29d39..c93f4b055 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,36 +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; - - default: - break; - } - } 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; @@ -515,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) @@ -524,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); } } @@ -562,16 +542,13 @@ 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]; - break; default: break; @@ -625,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]) { @@ -655,9 +632,8 @@ mo_update_request_length(mo_t *dev, int len, int block_len) break; } } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; + default: dev->packet_len = len; break; @@ -670,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; } @@ -703,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 { @@ -767,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; @@ -797,7 +773,8 @@ 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 @@ -822,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); @@ -839,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); @@ -932,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 @@ -942,7 +919,7 @@ 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 @@ -966,17 +943,17 @@ mo_blocks(mo_t *dev, int32_t *len, UNUSED(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"); } } @@ -1004,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; @@ -1045,7 +1022,7 @@ mo_format(mo_t *dev) return; } #else - fd = fileno(dev->drv->f); + fd = fileno(dev->drv->fp); ret = ftruncate(fd, 0); @@ -1084,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); @@ -1116,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; } @@ -1141,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 @@ -1206,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 @@ -1257,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 @@ -1306,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; @@ -1323,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], @@ -1344,9 +1322,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) mo_invalid_field(dev); return; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: @@ -1863,10 +1839,10 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) } #if 0 - mo_log("MO %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); + 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); } @@ -2105,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]; @@ -2123,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; @@ -2171,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]; @@ -2209,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 6eb60bd6d..d4b644865 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,36 +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; - - default: - break; - } - } 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; @@ -660,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) { @@ -676,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); } } @@ -791,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]) { @@ -821,9 +801,7 @@ zip_update_request_length(zip_t *dev, int len, int block_len) break; } } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; default: dev->packet_len = len; @@ -837,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; } @@ -870,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 { @@ -934,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; @@ -964,7 +942,8 @@ 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 @@ -989,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); @@ -1006,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); @@ -1099,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 @@ -1109,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 @@ -1142,17 +1121,17 @@ zip_blocks(zip_t *dev, int32_t *len, UNUSED(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"); } } @@ -1186,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; } @@ -1211,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 @@ -1276,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 @@ -1327,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 @@ -1375,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; @@ -1390,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], @@ -1411,9 +1391,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_invalid_field(dev); return; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: @@ -1469,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]; @@ -1511,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: @@ -1520,14 +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); */ @@ -1538,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); @@ -1562,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: @@ -1576,9 +1570,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_command_complete(dev); break; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case GPCMD_WRITE_6: case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: @@ -1596,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: @@ -1610,17 +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; } @@ -1635,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); @@ -1649,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: @@ -1671,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; } @@ -1699,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: @@ -1978,7 +1971,7 @@ atapi_out: 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; @@ -1987,7 +1980,7 @@ atapi_out: 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; @@ -2007,7 +2000,7 @@ atapi_out: 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; @@ -2017,7 +2010,7 @@ atapi_out: 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; @@ -2040,10 +2033,10 @@ atapi_out: } #if 0 - zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->phase, dev->request_length); + 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); } @@ -2123,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; @@ -2327,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]; @@ -2345,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; @@ -2393,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]; @@ -2431,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 a8ba1c1a9..55cf31236 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1271,8 +1271,6 @@ dma_sg(uint8_t *data, int transfer_length, int out, void *priv) } } } - - return 1; } uint8_t diff --git a/src/fifo.c b/src/fifo.c new file mode 100644 index 000000000..72084e11b --- /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/floppy/fdc.c b/src/floppy/fdc.c index bbe4c05db..f30d86168 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -36,6 +36,7 @@ #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]; @@ -167,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); @@ -179,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++; } @@ -190,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 @@ -213,6 +212,7 @@ fdc_ctrl_reset(void *priv) fdc->lock = 0; fdc->head = 0; fdc->step = 0; + fdc->power_down = 0; if (!(fdc->flags & FDC_FLAG_AT)) fdc->rate = 2; } @@ -258,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); @@ -271,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 @@ -293,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 @@ -322,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 @@ -334,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 @@ -419,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) { @@ -428,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); } @@ -491,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 @@ -501,37 +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; - - default: - break; - } - break; - case 2: /*Double density*/ - fdc->bit_rate = 250; - break; - case 3: /*Extended density*/ - fdc->bit_rate = 1000; - break; - - default: - 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*/ } @@ -689,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 @@ -742,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: @@ -777,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++) { @@ -855,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); @@ -867,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*/ @@ -889,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*/ @@ -908,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*/ @@ -916,9 +917,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc_bad_command(fdc); break; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x07: /*Recalibrate*/ fdc->pnum = 0; fdc->ptot = 1; @@ -927,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*/ @@ -961,15 +956,12 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc_bad_command(fdc); break; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + 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*/ @@ -977,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; @@ -985,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); @@ -1085,9 +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]; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x06: /* Read data */ case 0x0c: /* Read deleted data */ fdc_io_command_phase1(fdc, 0); @@ -1158,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 */ @@ -1280,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); @@ -1520,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); @@ -1551,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 */ @@ -1577,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; @@ -1722,7 +1718,6 @@ fdc_callback(void *priv) default: break; } - fdc->inread = 1; return; case 0x07: /* Recalibrate */ fdc->pcn[fdc->params[0] & 3] = 0; @@ -2011,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); } @@ -2032,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); } @@ -2040,7 +2027,6 @@ void fdc_sector_finishread(fdc_t *fdc) { fdc->stat = 0x10; - fdc->inread = 0; fdc_callback(fdc); } @@ -2363,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 @@ -2425,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/fdd.c b/src/floppy/fdd.c index 2d6892623..845a6f35e 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -454,7 +454,7 @@ fdd_load(int drive, char *fn) int c = 0; int size; const char *p; - FILE * f; + 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; @@ -563,8 +563,10 @@ fdd_poll(void *priv) if (fdd_notfound) { fdd_notfound--; +#ifdef RETURN_NOIDAM if (!fdd_notfound) fdc_noidam(fdd_fdc); +#endif } } diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 023296358..fa1c070f1 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1274,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; } @@ -1328,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; } } @@ -1347,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; } @@ -1433,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--; @@ -1458,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 { @@ -1576,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 @@ -1589,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++; } @@ -1597,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; @@ -1951,9 +1974,7 @@ d86f_format_track(int drive, int side, int do_write) if (dev->datac == 3) fdc_stop_id_request(d86f_fdc); } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case FMT_PRETRK_SYNC: case FMT_SECTOR_DATA_SYNC: @@ -2148,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++; } @@ -2165,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 @@ -2296,9 +2317,7 @@ d86f_turbo_poll(int drive, int side) case STATE_0D_SPIN_TO_INDEX: dev->sector_count = 0; dev->datac = 5; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case STATE_02_SPIN_TO_INDEX: dev->state++; @@ -2343,9 +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); -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case STATE_0A_FIND_ID: dev->turbo_pos = 0; @@ -3013,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 @@ -3053,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; @@ -3083,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]); } } } @@ -3102,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]); } } } diff --git a/src/floppy/fdi2raw.c b/src/floppy/fdi2raw.c index 75c65cf25..c6a41a52d 100644 --- a/src/floppy/fdi2raw.c +++ b/src/floppy/fdi2raw.c @@ -1503,12 +1503,12 @@ 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 } @@ -2162,7 +2162,7 @@ fdi2raw_get_tpi(FDI *fdi) } FDI * -fdi2raw_header(FILE *f) +fdi2raw_header(FILE *fp) { long i; long offset; @@ -2174,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); diff --git a/src/game/gameport.c b/src/game/gameport.c index 413a1ff5a..323555984 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -58,7 +58,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", @@ -128,21 +128,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 @@ -151,7 +151,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++; } @@ -183,22 +183,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 @@ -410,7 +410,7 @@ tmacm_init(UNUSED(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); @@ -428,7 +428,7 @@ tmacm_init(UNUSED(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/gdbstub.c b/src/gdbstub.c index 4fafb545e..703637422 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, @@ -220,8 +222,10 @@ static char target_xml[] = /* QEMU gdb-xml/i386-32bit.xml with modificati "" "" "" +#if 0 "" "" +#endif "" "" "" @@ -339,7 +343,7 @@ 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; @@ -546,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); @@ -625,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); @@ -678,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]; @@ -1015,13 +1023,8 @@ e14: /* 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. */ @@ -1097,7 +1100,7 @@ e00: } 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")) { @@ -1345,7 +1348,7 @@ unknown: /* 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 { @@ -1370,7 +1373,7 @@ end: } 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; @@ -1749,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 2f16c92d7..20f3fffcc 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 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 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 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[]); @@ -197,11 +214,15 @@ extern uint16_t get_last_addr(void); 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 11be67278..2b8a6396f 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -113,7 +113,8 @@ typedef struct acpi_regs_t { typedef struct acpi_t { acpi_regs_t regs; uint8_t gpireg2_default; - uint8_t pad[3]; + uint8_t irq_state; + uint8_t pad[2]; uint8_t gporeg_default[4]; uint8_t suspend_types[8]; uint16_t io_base; diff --git a/src/include/86box/agpgart.h b/src/include/86box/agpgart.h index fc2976c88..d3ed35c88 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. diff --git a/src/include/86box/bswap.h b/src/include/86box/bswap.h index 9f3c51917..ac758b20a 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/cdrom.h b/src/include/86box/cdrom.h index 69b4e90f3..d188c9243 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 @@ -60,12 +60,63 @@ enum { 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 +}; -static const struct { +#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]; @@ -73,42 +124,51 @@ static const struct { 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 }, + { "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. */ @@ -184,13 +244,14 @@ typedef struct cdrom { int prev_host_drive; int cd_buflen; int audio_op; + 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); @@ -213,12 +274,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); @@ -241,6 +306,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 67129dc7c..39faf9f33 100644 --- a/src/include/86box/cdrom_image_backend.h +++ b/src/include/86box/cdrom_image_backend.h @@ -45,17 +45,17 @@ 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 { +typedef struct track_t { int number; int track_number; int attr; @@ -70,7 +70,7 @@ typedef struct { track_file_t *file; } track_t; -typedef struct { +typedef struct cd_img_t { int tracks_num; track_t *tracks; } cd_img_t; @@ -97,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 860a436e0..081f758f6 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 9d6bd64cf..4aa3ee3e9 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; @@ -169,6 +174,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 72b0a709f..80c987162 100644 --- a/src/include/86box/config.h +++ b/src/include/86box/config.h @@ -28,21 +28,21 @@ extern "C" { #if 0 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, + 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: + 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 + wchar_t path[1024]; /* Name of current image file or host drive */ - uint32_t spt; /* Physical geometry parameters */ + uint32_t spt; /* Physical geometry parameters */ uint32_t hpc; uint32_t tracks; } storage_cfg_t; diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 74dd5ee3d..b2d7a05ed 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -41,39 +41,53 @@ #ifndef EMU_DEVICE_H #define EMU_DEVICE_H -#define CONFIG_END -1 -#define CONFIG_STRING 0 -#define CONFIG_INT 1 -#define CONFIG_BINARY 2 -#define CONFIG_SELECTION 3 -#define CONFIG_MIDI_OUT 4 -#define CONFIG_FNAME 5 -#define CONFIG_SPINNER 6 -#define CONFIG_HEX16 7 -#define CONFIG_HEX20 8 -#define CONFIG_MAC 9 -#define CONFIG_MIDI_IN 10 -#define CONFIG_BIOS 11 -#define CONFIG_SERPORT 12 +#define CONFIG_END -1 +#define CONFIG_STRING 0 +#define CONFIG_INT 1 +#define CONFIG_BINARY 2 +#define CONFIG_SELECTION 3 +#define CONFIG_MIDI_OUT 4 +#define CONFIG_FNAME 5 +#define CONFIG_SPINNER 6 +#define CONFIG_HEX16 7 +#define CONFIG_HEX20 8 +#define CONFIG_MAC 9 +#define CONFIG_MIDI_IN 10 +#define CONFIG_BIOS 11 +#define CONFIG_SERPORT 12 + +#define CONFIG_ONBOARD 256 /* only avaialble on the on-board variant */ +#define CONFIG_STANDALONE 257 /* not available on the on-board variant */ enum { DEVICE_PCJR = 2, /* requires an IBM PCjr */ - 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 */ }; @@ -135,8 +149,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); @@ -155,37 +168,37 @@ 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_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_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); @@ -202,7 +215,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/fdc.h b/src/include/86box/fdc.h index 9441bdfc4..09c9c4578 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -65,76 +65,85 @@ typedef struct fdc_t { 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 params[8]; - uint8_t res[11]; - uint8_t specify[2]; 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 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 head; - int sector; - int drive; - int lastdrive; - int pcn[4]; - int eot[4]; - int rw_track; - int pos; - int pnum; - int ptot; - int rate; - int reset_stat; - int lock; - int perp; - int format_state; - int format_n; - int step; - int seek_dir; - int tc; - int noprec; + int bit_rate; /* Should be 250 at start. */ - int data_ready; - int inread; int bitcell_period; - int enh_mode; - int rwc[4]; - int drvrate[4]; int boot_drive; - int dma; - int densel_polarity; - int densel_force; - int fifo; - int tfifo; - int fifobufpos; - int drv2en; - int gap; - int enable_3f1; - int format_sectors; int max_track; - int mfm; - int deleted; - int wrong_am; - int sc; int satisfying_sectors; - int fintr; - int rw_drive; int flags; int interrupt; - int irq; /* Should be 6 by default. */ - int dma_ch; /* Should be 2 by default. */ + 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; + int drvrate[4]; sector_id_t read_track_sector; sector_id_t format_sector_id; @@ -183,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 106235658..0d821ac11 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 e21cbb73e..0331f4fcc 100644 --- a/src/include/86box/fdd.h +++ b/src/include/86box/fdd.h @@ -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 000000000..e76189d8a --- /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/filters.h b/src/include/86box/filters.h index f93695433..dfe19c654 100644 --- a/src/include/86box/filters.h +++ b/src/include/86box/filters.h @@ -197,8 +197,8 @@ low_iir(int c, int i, double NewSample) 0.93726236021404663000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -232,8 +232,8 @@ low_cut_iir(int c, int i, double NewSample) 0.93726236021916731000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -266,8 +266,8 @@ high_iir(int c, int i, double NewSample) -1.36640781670578510000, 0.52352474706139873000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -300,8 +300,8 @@ high_cut_iir(int c, int i, double NewSample) -1.36640781666419950000, 0.52352474703279628000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -334,8 +334,8 @@ deemph_iir(int i, double NewSample) -1.05429146278569141337, 0.26412280202756849290 }; - static double y[2][NCoef + 1]; /* output samples */ - static double x[2][NCoef + 1]; /* input samples */ + static double y[3][NCoef + 1]; /* output samples */ + static double x[3][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -372,8 +372,8 @@ sb_iir(int c, int i, double NewSample) 0.55326988968868285000 }; - static double y[2][2][NCoef + 1]; /* output samples */ - static double x[2][2][NCoef + 1]; /* input samples */ + static double y[3][2][NCoef + 1]; /* output samples */ + static double x[3][2][NCoef + 1]; /* input samples */ int n; /* shift the old samples */ @@ -395,13 +395,13 @@ sb_iir(int c, int i, double NewSample) #define NCoef 1 #define SB16_NCoef 51 -extern double low_fir_sb16_coef[2][SB16_NCoef]; +extern double low_fir_sb16_coef[3][SB16_NCoef]; static inline double low_fir_sb16(int c, int i, double NewSample) { - static double x[2][2][SB16_NCoef + 1]; // input samples - static int pos[2] = { 0, 0 }; + static double x[3][2][SB16_NCoef + 1]; // input samples + static int pos[3] = { 0, 0 }; double out = 0.0; int n; diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index 3b779e4e3..ba3568464 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -24,6 +24,16 @@ #define MAX_PLAT_JOYSTICKS 8 #define MAX_JOYSTICKS 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 @@ -84,11 +94,11 @@ typedef struct joystick_if_t { 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 (*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; int button_count; @@ -133,16 +143,16 @@ 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); diff --git a/src/include/86box/gdbstub.h b/src/include/86box/gdbstub.h index 5d55615b3..c58a58bf5 100644 --- a/src/include/86box/gdbstub.h +++ b/src/include/86box/gdbstub.h @@ -36,19 +36,19 @@ enum { #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 64fd88659..b0e775886 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -60,6 +60,9 @@ 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_ali1489_device; /* ALi M1489 */ +extern const device_t ide_ali5213_device; /* ALi M5213 */ + 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) */ @@ -95,7 +98,7 @@ 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 8a4c66da3..1f7a78c9f 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -28,26 +28,61 @@ #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 { + /* The rest. */ uint8_t selected; - uint8_t atastat; - uint8_t error; uint8_t command; - uint8_t fdisk; + uint8_t head; + uint8_t pad; int type; int board; int irqstat; @@ -56,18 +91,11 @@ typedef struct ide_s { int blockcount; int hdd_num; int channel; - int pos; int sector_pos; - int lba; int reset; int mdma_mode; int do_initial_read; - uint32_t secount; - uint32_t sector; - uint32_t cylinder; - uint32_t head; uint32_t drive; - uint32_t cylprecomp; uint32_t cfg_spt; uint32_t cfg_hpc; uint32_t lba_addr; @@ -80,24 +108,44 @@ typedef struct ide_s { 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, @@ -132,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 @@ -141,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); @@ -149,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_base_addr(int board, int base, uint16_t port); -extern void ide_set_handlers(uint8_t board); -extern void ide_remove_handlers(uint8_t board); - -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 @@ -180,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 490a13a42..2283497bb 100644 --- a/src/include/86box/hdc_ide_sff8038i.h +++ b/src/include/86box/hdc_ide_sff8038i.h @@ -20,52 +20,62 @@ #ifndef EMU_HDC_IDE_SFF8038I_H #define EMU_HDC_IDE_SFF8038I_H -typedef struct sff8038i_t { +enum +{ + IRQ_MODE_LEGACY = 0, + IRQ_MODE_PCI_IRQ_PIN, + IRQ_MODE_PCI_IRQ_LINE, + IRQ_MODE_ALI_ALADDIN, + IRQ_MODE_MIRQ_0, + IRQ_MODE_MIRQ_1, + IRQ_MODE_MIRQ_2, + IRQ_MODE_MIRQ_3, + IRQ_MODE_SIS_551X +}; + +typedef struct sff8038i_t +{ uint8_t command; uint8_t status; uint8_t ptr0; uint8_t enabled; uint8_t dma_mode; - uint8_t pad; - uint8_t pad0; - uint8_t pad1; + uint8_t irq_state; + uint8_t channel; + uint8_t irq_line; uint16_t base; - uint16_t pad2; + uint16_t pad; uint32_t ptr; uint32_t ptr_cur; uint32_t addr; int count; int eot; int slot; - int irq_mode[2]; - int irq_level[2]; + int irq_mode; + int irq_level; int irq_pin; - int irq_line; + int pci_irq_line; } sff8038i_t; extern const device_t sff8038i_device; extern void sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base); -extern int sff_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv); -extern int sff_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv); - -extern void sff_bus_master_set_irq(int channel, void *priv); - -extern int sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv); +extern void sff_bus_master_set_irq(uint8_t status, void *priv); +extern int sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv); extern void sff_bus_master_write(uint16_t port, uint8_t val, void *priv); extern uint8_t sff_bus_master_read(uint16_t port, void *priv); -extern void sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base); +extern void sff_bus_master_reset(sff8038i_t *dev); extern void sff_set_slot(sff8038i_t *dev, int slot); extern void sff_set_irq_line(sff8038i_t *dev, int irq_line); -extern void sff_set_irq_mode(sff8038i_t *dev, int channel, int irq_mode); +extern void sff_set_irq_mode(sff8038i_t *dev, int irq_mode); extern void sff_set_irq_pin(sff8038i_t *dev, int irq_pin); -extern void sff_set_irq_level(sff8038i_t *dev, int channel, int irq_level); +extern void sff_set_irq_level(sff8038i_t *dev, int irq_level); #endif /*EMU_HDC_IDE_SFF8038I_H*/ diff --git a/src/include/86box/hdd.h b/src/include/86box/hdd.h index 9874fb4aa..89a6cf1ff 100644 --- a/src/include/86box/hdd.h +++ b/src/include/86box/hdd.h @@ -148,7 +148,8 @@ typedef struct hard_disk_t { uint8_t scsi_id; }; uint8_t bus; - uint8_t res; /* Reserved for bus mode */ + uint8_t bus_mode; /* Bit 0 = PIO suported; + Bit 1 = DMA supportd. */ uint8_t wp; /* Disk has been mounted READ-ONLY */ uint8_t pad; uint8_t pad0; @@ -158,8 +159,8 @@ typedef struct hard_disk_t { char fn[1024]; /* Name of current image file */ char vhd_parent[1041]; /* Differential VHD parent file */ - uint32_t res0; - uint32_t pad1; + uint32_t seek_pos; + uint32_t seek_len; uint32_t base; uint32_t spt; uint32_t hpc; /* Physical geometry parameters */ diff --git a/src/include/86box/hwm.h b/src/include/86box/hwm.h index b1b1d8c25..4ad5e6917 100644 --- a/src/include/86box/hwm.h +++ b/src/include/86box/hwm.h @@ -68,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 b5ba3c7a4..9a25b5d1b 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 866787352..d52620f69 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 71c1bb29a..5e48b7c18 100644 --- a/src/include/86box/isapnp.h +++ b/src/include/86box/isapnp.h @@ -54,17 +54,21 @@ typedef struct isapnp_device_config_t { } 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 d619d3052..92c58e350 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/keyboard.h b/src/include/86box/keyboard.h index b84733d9c..a4b079760 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -47,7 +47,7 @@ typedef struct kbc_at_port_t { 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. */ @@ -226,6 +226,7 @@ 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; diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index 4c1c793ae..a9a9eac65 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -21,13 +21,13 @@ 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,19 +53,19 @@ extern void lpt1_remove_ams(void); #define lpt4_remove() lpt_port_remove(3) #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 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 { +typedef struct lpt_port_t { uint8_t enabled; uint8_t irq; uint8_t dat; @@ -83,10 +83,11 @@ 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_status(int port); +extern void lpt_irq(void *priv, int raise); -extern char *lpt_device_get_name(int id); -extern char *lpt_device_get_internal_name(int id); +extern const char *lpt_device_get_name(int id); +extern const char *lpt_device_get_internal_name(int id); extern int lpt_device_get_from_internal_name(char *s); diff --git a/src/include/86box/m_at_t3100e.h b/src/include/86box/m_at_t3100e.h index c25d171b9..b9c2e24df 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 d8e8cd56b..90916444c 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 0336723d5..dac5cbe54 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -28,18 +28,26 @@ #define MACHINE_BUS_ISA 0x00000001 /* sys has ISA bus */ #define MACHINE_BUS_CASSETTE 0x00000002 /* sys has cassette port */ #define MACHINE_BUS_CARTRIDGE 0x00000004 /* sys has two cartridge bays */ -#define MACHINE_BUS_ISA16 0x00000008 /* sys has ISA16 bus - PC/AT architecture */ -#define MACHINE_BUS_CBUS 0x00000010 /* sys has C-BUS bus */ -#define MACHINE_BUS_PS2_LATCH 0x00000020 /* system has PS/2 keyboard controller IRQ latch */ -#define MACHINE_BUS_PS2_PORTS 0x00000040 /* system has PS/2 keyboard and mouse ports */ +#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_EISA 0x00000080 /* sys has EISA bus */ -#define MACHINE_BUS_VLB 0x00000100 /* sys has VL bus */ -#define MACHINE_BUS_MCA 0x00000200 /* sys has MCA bus */ -#define MACHINE_BUS_PCI 0x00000400 /* sys has PCI bus */ -#define MACHINE_BUS_PCMCIA 0x00000800 /* sys has PCMCIA bus */ -#define MACHINE_BUS_AGP 0x00001000 /* sys has AGP bus */ -#define MACHINE_BUS_AC97 0x00002000 /* sys has AC97 bus (ACR/AMR/CNR slot) */ +#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_CASSETTE (MACHINE_BUS_CASSETTE) /* sys has cassette port */ #define MACHINE_CARTRIDGE (MACHINE_BUS_CARTRIDGE) /* sys has two cartridge bays */ @@ -73,61 +81,65 @@ #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 */ /* 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_SOFTFLOAT_ONLY 0x20000000 /* sys requires softfloat FPU */ +#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) @@ -277,20 +289,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; - uintptr_t pad0; - uintptr_t pad1; - uintptr_t 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; @@ -302,10 +315,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 @@ -328,18 +338,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); @@ -349,24 +360,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 *); @@ -419,6 +446,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 *); @@ -563,7 +591,7 @@ 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 *); extern int machine_at_deskpro386_init(const machine_t *); -extern int machine_at_deskpro386_01_1988_init(const machine_t *); +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); @@ -590,6 +618,7 @@ 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 *); @@ -614,6 +643,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 *); @@ -626,6 +656,7 @@ 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_dell_430vx_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); @@ -638,6 +669,7 @@ 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 *); @@ -661,6 +693,7 @@ 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 *); @@ -671,6 +704,7 @@ 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_cb52x_si_init(const machine_t *); extern int machine_at_m560_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); @@ -692,7 +726,9 @@ 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_lgibm440fx_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 *); @@ -711,9 +747,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_mate_nx_ma30d_23d_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_lgibm440bx_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 *); @@ -741,6 +780,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 *); @@ -830,6 +870,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/mem.h b/src/include/86box/mem.h index 30e9359bf..69a2b5de8 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -331,6 +331,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); @@ -429,6 +447,9 @@ extern void mem_close(void); extern void mem_reset(void); extern void mem_remap_top(int kb); +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 af7fd217d..4bc678817 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); @@ -78,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 *priv); +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); @@ -102,6 +102,7 @@ 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; +extern const device_t opl4_midi_device; # 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 a11c4d636..5d4b723f3 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -27,6 +27,8 @@ #define MO_TIME 10.0 +#define MO_IMAGE_HISTORY 4 + typedef struct mo_type_t { uint32_t sectors; uint16_t bytes_per_sector; @@ -35,17 +37,17 @@ typedef struct mo_type_t { #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 mo_drive_type_t { @@ -58,7 +60,7 @@ typedef struct mo_drive_type_t { #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 }}, @@ -107,12 +109,14 @@ typedef struct mo_drive_t { uint8_t pad; uint8_t pad0; - FILE *f; + FILE *fp; void *priv; char image_path[1024]; char prev_image_path[1024]; + char *image_history[MO_IMAGE_HISTORY]; + uint32_t type; uint32_t medium_size; uint32_t base; @@ -124,23 +128,35 @@ 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; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; - uint8_t status; - uint8_t phase; - uint8_t error; - uint8_t id; +#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 id; uint8_t cur_lun; uint8_t pad0; uint8_t pad1; - uint16_t request_length; uint16_t max_transfer_len; + uint16_t pad2; int requested_blocks; int packet_status; @@ -154,15 +170,16 @@ typedef struct mo_t { uint32_t sector_pos; uint32_t sector_len; uint32_t packet_len; - uint32_t pos; 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 839c0f11a..3ed6b2126 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_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 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,50 @@ 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_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_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_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_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 index 996720f8f..c55151ab8 100644 --- a/src/include/86box/net_3c501.h +++ b/src/include/86box/net_3c501.h @@ -11,7 +11,7 @@ * * * - * Based on @(#)Dev3C501.cpp Oracle (VirtualBox) + * Based on @(#)Dev3C501.cpp Oracle (VirtualBox) * * Authors: TheCollector1995, * Oracle diff --git a/src/include/86box/net_eeprom_nmc93cxx.h b/src/include/86box/net_eeprom_nmc93cxx.h new file mode 100644 index 000000000..f5260d1ed --- /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_rtl8139.h b/src/include/86box/net_rtl8139.h new file mode 100644 index 000000000..f44d0facb --- /dev/null +++ b/src/include/86box/net_rtl8139.h @@ -0,0 +1 @@ +extern const device_t rtl8139c_plus_device; diff --git a/src/include/86box/net_tulip.h b/src/include/86box/net_tulip.h new file mode 100644 index 000000000..3e14deeea --- /dev/null +++ b/src/include/86box/net_tulip.h @@ -0,0 +1,3 @@ +extern const device_t dec_tulip_device; +extern const device_t dec_tulip_21140_device; +extern const device_t dec_tulip_21140_vpc_device; diff --git a/src/include/86box/network.h b/src/include/86box/network.h index d7958ee9a..e9b703ee0 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -78,13 +78,9 @@ enum { NET_LINK_1000_FD = (1 << 8), }; -/* Supported network cards. */ enum { - NONE = 0, - NE1000 = 1, - NE2000 = 2, - RTL8019AS = 3, - RTL8029AS = 4 + NET_NONE = 0, + NET_INTERNAL }; enum { @@ -194,7 +190,7 @@ 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 *); extern const device_t *network_card_getdevice(int); diff --git a/src/include/86box/nmi.h b/src/include/86box/nmi.h index 319d63b6b..79aa68346 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 baba6b6c4..d24ca903c 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -85,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; @@ -126,5 +127,8 @@ 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 000000000..248b1f729 --- /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 5ef0d9488..f1c5e4177 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 df9c4c573..2bcb6b3b8 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -11,146 +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_IO 0x01 -#define PCI_COMMAND_MEM 0x02 +#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_NO_IRQ_STEERING 0x8000 -#define PCI_CAN_SWITCH_TYPE 0x10000 -#define PCI_NO_BRIDGES 0x20000 -#define PCI_ALWAYS_EXPOSE_DEV0 0x40000 +#define PCI_COMMAND_H_SERR 0x01 +#define PCI_COMMAND_H_FAST_B2B 0x02 +#define PCI_COMMAND_H_INT_DIS 0x04 -#define PCI_CONFIG_TYPE_1 1 -#define PCI_CONFIG_TYPE_2 2 +#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_CONFIG_TYPE_MASK 0x7fff +#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_INTA 1 -#define PCI_INTB 2 -#define PCI_INTC 3 -#define PCI_INTD 4 +#define PCI_DEVSEL_FAST 0x00 +#define PCI_DEVSEL_MEDIUM 0x02 +#define PCI_DEVSEL_SLOW 0x04 -#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 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 PCI_IRQ_DISABLED -1 +#define FLAG_MECHANISM_MASK FLAG_MECHANISM_1 | FLAG_MECHANISM_2 +#define FLAG_MASK 0x0000007f -#define PCI_ADD_STRICT 0x80 +#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_CARD_VFIO PCI_ADD_VFIO + +#define PCI_BUS_INVALID 0xff + +#define PCI_IGNORE_NO_SLOT 0xff + +/* 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) + +/* Legacy flags. */ +#define PCI_REG_COMMAND PCI_REG_COMMAND_L + +#define PCI_COMMAND_IO PCI_COMMAND_L_IO +#define PCI_COMMAND_MEM PCI_COMMAND_L_MEM + +#define PCI_CONFIG_TYPE_1 FLAG_MECHANISM_1 +#define PCI_CONFIG_TYPE_2 FLAG_MECHANISM_2 + +#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 = 1, - PCI_CARD_SOUTHBRIDGE = 2, - PCI_CARD_SOUTHBRIDGE_IDE = 3, - PCI_CARD_SOUTHBRIDGE_PMU = 4, - PCI_CARD_SOUTHBRIDGE_USB = 5, + 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_SCSI = 0x12, - PCI_CARD_SOUND = 0x13, - PCI_CARD_IDE = 0x14, - PCI_CARD_NETWORK = 0x15, - PCI_CARD_BRIDGE = 0x16 + 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 = 1, - PCI_ADD_SOUTHBRIDGE = 2, - PCI_ADD_SOUTHBRIDGE_IDE = 3, - PCI_ADD_SOUTHBRIDGE_PMU = 4, - PCI_ADD_SOUTHBRIDGE_USB = 5, + 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_SCSI = 0x12, - PCI_ADD_SOUND = 0x13, - PCI_ADD_IDE = 0x14, - PCI_ADD_NETWORK = 0x15, - PCI_ADD_BRIDGE = 0x16 + 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; +} pci_bar_t; +extern int pci_burst_time; +extern int agp_burst_time; +extern int pci_nonburst_time; +extern int agp_nonburst_time; -#define PCI_IO_ON 0x01 -#define PCI_IO_DEV0 0x02 +extern int pci_flags; +extern uint32_t pci_base; +extern uint32_t pci_size; -extern int pci_burst_time; -extern int agp_burst_time; -extern int pci_nonburst_time; -extern int agp_nonburst_time; -extern int pci_take_over_io; +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); -extern uint32_t pci_base; -extern uint32_t pci_size; +/* 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); -extern void pci_type2_write(uint16_t port, uint8_t val, void *priv); -extern void pci_type2_writew(uint16_t port, uint16_t val, void *priv); -extern void pci_type2_writel(uint16_t port, uint32_t val, void *priv); -extern uint8_t pci_type2_read(uint16_t port, void *priv); -extern uint16_t pci_type2_readw(uint16_t port, void *priv); -extern uint32_t pci_type2_readl(uint16_t port, void *priv); +/* 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 void pci_set_irq_routing(int pci_int, int irq); -extern void pci_set_irq_level(int pci_int, int level); +/* Write PCI enable/disable key, split for the ALi M1435. */ +extern void pci_key_write(uint8_t val); -extern void pci_enable_mirq(int mirq); -extern void pci_set_mirq_routing(int mirq, int irq); +/* Set PMC (ie. change PCI configuration mechanism), 0 = #2, 1 = #1. */ +extern void pci_set_pmc(uint8_t pmc); -extern int pci_irq_is_level(int irq); +extern void pci_pic_reset(void); +extern void pci_reset(void); -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); +/* 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_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); +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 trc_init(void); +/* 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 uint8_t trc_read(uint16_t port, void *priv); -extern void trc_write(uint16_t port, uint8_t val, void *priv); +/* 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 void pci_bridge_set_ctl(void *priv, uint8_t ctl); +/* Register the cards that have been added into slots. */ +extern void pci_register_cards(void); -extern void pci_pic_reset(void); +extern void pci_init(int flags); + +/* PCI bridge stuff. */ +extern void pci_bridge_set_ctl(void *priv, uint8_t ctl); #ifdef EMU_DEVICE_H extern const device_t dec21150_device; diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index dcc6f1358..798cc3357 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -19,6 +19,13 @@ #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; uint8_t icw2; @@ -38,8 +45,13 @@ typedef struct pic { uint8_t special_mask_mode; uint8_t auto_eoi_rotate; uint8_t interrupt; - uint8_t lines; 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; @@ -69,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 bb6c26969..d288b7e6c 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -128,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 a7caeabe7..2485a360c 100644 --- a/src/include/86box/pit_fast.h +++ b/src/include/86box/pit_fast.h @@ -69,6 +69,8 @@ typedef struct pitf_t { uint8_t ctrl; } pitf_t; +extern uint8_t pitf_read_reg(void *priv, uint8_t reg); + extern const pit_intf_t pit_fast_intf; #ifdef EMU_DEVICE_H diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 932dfe87b..0d5b17a3c 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,6 +80,19 @@ 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 */ extern int mouse_capture; /* mouse is captured in app */ @@ -94,6 +107,7 @@ extern int infocus; extern char emu_version[200]; /* version ID string */ extern int rctrl_is_lalt; extern int update_icons; +extern int status_icons_fullscreen; extern int kbd_req_capture; extern int hide_status_bar; @@ -133,6 +147,8 @@ 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); /* 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 485314f46..965483d26 100644 --- a/src/include/86box/plat_dir.h +++ b/src/include/86box/plat_dir.h @@ -40,23 +40,23 @@ struct dirent { # define d_namlen d_reclen 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 */ + 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 *); diff --git a/src/include/86box/plat_fallthrough.h b/src/include/86box/plat_fallthrough.h new file mode 100644 index 000000000..6165b266c --- /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 e9df0584e..60674ea58 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 index 73eaebaae..226cf677d 100644 --- a/src/include/86box/plat_unused.h +++ b/src/include/86box/plat_unused.h @@ -21,11 +21,13 @@ #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/printer.h b/src/include/86box/printer.h index eb6eb4a75..b576fbf27 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 2080c3a3b..20067aa40 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 */ diff --git a/src/include/86box/rom.h b/src/include/86box/rom.h index e4c50ac01..1f6e611b1 100644 --- a/src/include/86box/rom.h +++ b/src/include/86box/rom.h @@ -48,9 +48,9 @@ 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); diff --git a/src/include/86box/row.h b/src/include/86box/row.h index 9dab7d4c3..a70c94274 100644 --- a/src/include/86box/row.h +++ b/src/include/86box/row.h @@ -1,25 +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. + * 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 SMRAM interface. + * Definitions for the SMRAM interface. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2020 Miran Grca. */ #ifndef EMU_ROW_H # define EMU_ROW_H -typedef struct _row_ -{ +typedef struct _row_ { struct _smram_ *prev; struct _smram_ *next; @@ -35,12 +34,9 @@ typedef struct _row_ 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*/ +#endif /*EMU_ROW_H*/ diff --git a/src/include/86box/scsi.h b/src/include/86box/scsi.h index d19497101..376ac79b9 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 3c8265391..800d2d72b 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 12bff6fdf..6de69e700 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 64c24c10e..dec537429 100644 --- a/src/include/86box/scsi_cdrom.h +++ b/src/include/86box/scsi_cdrom.h @@ -26,24 +26,36 @@ 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 status; - uint8_t phase; - uint8_t error; - uint8_t id; +#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 id; uint8_t cur_lun; uint8_t early; uint8_t pad1; - uint16_t request_length; uint16_t max_transfer_len; + uint16_t pad2; int requested_blocks; int packet_status; @@ -57,13 +69,12 @@ typedef struct scsi_cdrom_t { uint32_t sector_pos; uint32_t sector_len; uint32_t packet_len; - uint32_t pos; 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 7256970cd..09f9ee2d9 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -149,6 +149,7 @@ #define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA 0xe9 /* Matsushita Vendor Unique command */ /* Mode page codes for mode sense/set */ +#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 @@ -165,6 +166,7 @@ #define GPMODE_ALL_PAGES 0x3f /* Mode page codes for presence */ +#define GPMODEP_UNIT_ATN_PAGE 0x0000000000000001LL #define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL #define GPMODEP_DISCONNECT_PAGE 0x0000000000000004LL #define GPMODEP_FORMAT_DEVICE_PAGE 0x0000000000000008LL @@ -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 @@ -347,7 +349,12 @@ typedef struct mode_sense_pages_t { 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; uint8_t atapi_cdb[16]; /* This is atapi_cdb in ATAPI-supporting devices, @@ -355,17 +362,24 @@ typedef struct scsi_common_s { uint8_t current_cdb[16]; uint8_t sense[256]; - uint8_t status; - uint8_t phase; - uint8_t error; - uint8_t id; +#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 id; uint8_t cur_lun; uint8_t pad0; uint8_t pad1; - uint16_t request_length; uint16_t max_transfer_len; + uint16_t pad2; int requested_blocks; int packet_status; @@ -379,7 +393,6 @@ typedef struct scsi_common_s { uint32_t sector_pos; uint32_t sector_len; uint32_t packet_len; - uint32_t pos; double callback; } scsi_common_t; @@ -393,11 +406,11 @@ typedef struct scsi_device_t { 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. */ @@ -435,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 ebf21c073..eb4dc69a4 100644 --- a/src/include/86box/scsi_disk.h +++ b/src/include/86box/scsi_disk.h @@ -20,44 +20,56 @@ 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; - uint8_t pad[16]; /* This is atapi_cdb in ATAPI-supporting devices, - and pad in SCSI-only devices. */ - uint8_t current_cdb[16]; - uint8_t sense[256]; + uint8_t atapi_cdb[16]; + uint8_t current_cdb[16]; + uint8_t sense[256]; - uint8_t status; +#ifdef ANCIENT_CODE + /* Task file. */ + uint8_t features; uint8_t phase; - uint8_t error; - uint8_t id; - uint8_t pad0; - uint8_t cur_lun; - uint8_t pad1; - uint8_t pad2; - uint16_t request_length; - uint16_t pad4; + uint8_t status; + uint8_t error; + uint16_t pad; + uint32_t pos; +#endif + + 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 pad5; + int request_pos; int pad6; int pad7; uint32_t sector_pos; uint32_t sector_len; uint32_t packet_len; - uint32_t pos; 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 0ce353d33..3acee78f9 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 bfa579c82..057271772 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 213873c5a..0f1874302 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 */ @@ -256,11 +256,11 @@ typedef struct Mailbox32_t { Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block */ typedef struct CCB32_t { - uint8_t Opcode; - uint8_t Reserved1 : 3, - ControlByte : 2, - TagQueued : 1, - QueueTag : 2; + 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,9 +269,9 @@ typedef struct CCB32_t { 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; @@ -296,9 +296,9 @@ typedef struct CCB_t { 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]; @@ -311,8 +311,8 @@ typedef struct CCBC_t { typedef union CCBU_t { CCB32 new; - CCB old; - CCBC common; + CCB old; + CCBC common; } CCBU; typedef struct { @@ -329,9 +329,9 @@ 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 chs_t { uint16_t cyl; @@ -345,7 +345,7 @@ typedef struct BIOSCMD_t { uint8_t lba3; /* LSB */ } lba; } u; - uint8_t secount; + uint8_t secount; addr24_t dma_address; } BIOSCMD; @@ -366,6 +366,7 @@ typedef struct SGE_t { #define X54X_INT_GEOM_WRITABLE 8 #define X54X_MBX_24BIT 16 #define X54X_ISAPNP 32 +#define X54X_HAS_SIGNATURE 64 typedef struct x54x_t { /* 32 bytes */ @@ -379,7 +380,7 @@ typedef struct x54x_t { int8_t DmaChannel; int8_t HostID; - uint8_t callback_phase : 4; + uint8_t callback_phase : 4; uint8_t callback_sub_phase : 4; uint8_t scsi_cmd_phase; uint8_t bus; @@ -396,11 +397,15 @@ typedef struct x54x_t { 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 Interrupt; volatile uint8_t MailboxIsBIOS; volatile uint8_t ToRaise; volatile uint8_t flags; @@ -437,7 +442,7 @@ typedef struct x54x_t { volatile int PendingInterrupt; volatile int Lock; volatile int target_data_len; - volatile int pad0; + volatile int pad2; uint32_t Base; uint32_t fdc_address; @@ -478,31 +483,31 @@ typedef struct x54x_t { 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 */ rom_t uppersck; /* BIOS memory descriptor */ diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index b27e54c5e..bd7e85a91 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -65,29 +65,21 @@ typedef struct serial_s { uint8_t inst; uint8_t transmit_enabled; uint8_t fifo_enabled; - uint8_t rcvr_fifo_len; uint8_t bits; uint8_t data_bits; uint8_t baud_cycles; - uint8_t rcvr_fifo_full; uint8_t txsr; - uint8_t out; + uint8_t txsr_empty; uint8_t msr_set; - uint8_t pad; - uint8_t pad0; - uint8_t pad1; + uint8_t irq_state; uint16_t dlab; uint16_t base_address; uint16_t out_new; - uint16_t pad2; + uint16_t thr_empty; - uint8_t rcvr_fifo_pos; - uint8_t xmit_fifo_pos; - uint8_t rcvr_fifo_end; - uint8_t xmit_fifo_end; - uint8_t rcvr_fifo[SERIAL_FIFO_SIZE]; - uint8_t xmit_fifo[SERIAL_FIFO_SIZE]; + void *rcvr_fifo; + void *xmit_fifo; pc_timer_t transmit_timer; pc_timer_t timeout_timer; @@ -99,10 +91,10 @@ typedef struct serial_s { } 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; @@ -113,16 +105,16 @@ typedef struct serial_port_s { 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); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index d3bccca84..b07e73e8e 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -19,6 +19,7 @@ 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; @@ -45,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; @@ -74,7 +76,10 @@ extern const device_t ps1_m2133_sio; extern const device_t sio_detect_device; #endif 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/snd_ad1848.h b/src/include/86box/snd_ad1848.h index be7831fb4..6bdd2bf40 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -67,8 +67,8 @@ typedef struct ad1848_t { 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 63a0ff243..8aae3f1ff 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 0da6fcdab..8eec22935 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 dd01eaac0..090ab662a 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -668,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 ed8b89de7..8cd275af8 100644 --- a/src/include/86box/snd_mpu401.h +++ b/src/include/86box/snd_mpu401.h @@ -177,9 +177,9 @@ typedef struct mpu_t { 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; + void (*ext_irq_update)(void *priv, int set); + int (*ext_irq_pending)(void *priv); + void *priv; } mpu_t; extern int mpu401_standalone_enable; @@ -197,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 3a3f93ad5..0d89589c4 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -32,12 +32,13 @@ enum fm_driver { }; typedef struct fm_drv_t { - uint8_t (*read)(uint16_t port, void *priv); - void (*write)(uint16_t port, uint8_t val, void *priv); + 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 f82e85b0e..e53f860f1 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 710ff4a61..4ddaf9b91 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 4c6b2bba7..f433dd107 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -25,15 +25,18 @@ #include <86box/snd_opl.h> #include <86box/snd_sb_dsp.h> -#define SADLIB 1 /* No DSP */ -#define SB1 2 /* DSP v1.05 */ -#define SB15 3 /* DSP v2.00 */ -#define SB2 4 /* DSP v2.01 - needed for high-speed DMA */ -#define SBPRO 5 /* DSP v3.00 */ -#define SBPRO2 6 /* DSP v3.02 + OPL3 */ -#define SB16 7 /* DSP v4.05 + OPL3 */ -#define SBAWE32 8 /* DSP v4.13 + OPL3 */ -#define SBAWE64 9 /* DSP v4.16 + OPL3 */ +enum { + SADLIB = 1, /* No DSP */ + SB1, /* DSP v1.05 */ + SB15, /* DSP v2.00 */ + SB2, /* DSP v2.01 - needed for high-speed DMA */ + SBPRO, /* DSP v3.00 */ + SBPRO2, /* DSP v3.02 + OPL3 */ + SB16, /* DSP v4.05 + OPL3 */ + SBAWE32, /* DSP v4.12 + OPL3 */ + SBAWE32PNP, /* DSP v4.13 + OPL3 */ + SBAWE64 /* DSP v4.16 + OPL3 */ +}; /* SB 2.0 CD version */ typedef struct sb_ct1335_mixer_t { @@ -71,7 +74,6 @@ typedef struct sb_ct1345_mixer_t { uint8_t index; uint8_t regs[256]; - } sb_ct1345_mixer_t; /* SB16 and AWE32 */ @@ -142,28 +144,30 @@ typedef struct sb_t { void *gameport; int pos; + int pnp; 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 86f1ee529..ecabe426d 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -33,6 +33,10 @@ typedef struct sb_dsp_t { int sb_16_autolen; int sb_16_output; int sb_16_dmanum; + int sb_16_8_dmanum; + int sb_16_dma_enabled; + int sb_16_dma_supported; + int sb_16_dma_translate; int sb_pausetime; int (*dma_readb)(void *priv); int (*dma_readw)(void *priv); @@ -132,35 +136,39 @@ typedef struct sb_dsp_t { mpu_t *mpu; } sb_dsp_t; -void sb_dsp_input_msg(void *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/sound.h b/src/include/86box/sound.h index 4c01f289c..60628ece8 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/thread.h b/src/include/86box/thread.h index 3f09bf8f9..4d5584787 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 @@ -44,3 +65,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 e38ac51a3..4ade8aab0 100644 --- a/src/include/86box/timer.h +++ b/src/include/86box/timer.h @@ -7,12 +7,12 @@ #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 ts_struct_t -{ +typedef struct ts_struct_t { uint32_t frac; uint32_t integer; } ts_struct_t; @@ -117,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) @@ -176,45 +183,8 @@ timer_set_p(pc_timer_t *timer, void *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->priv); - } - - 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 000000000..00abed3ff --- /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 7c2e13ee9..623746829 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,188 +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 = 1, - USB_BUS_MAX = 2 -}; - -/* USB device creation parameters struct */ -typedef struct usb_params_t -{ - 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 { uint8_t uhci_io[32]; - ohci_mmio_t ohci_mmio[1024]; + uint8_t ohci_mmio[4096]; uint16_t uhci_io_base; int uhci_enable; int ohci_enable; uint32_t ohci_mem_base; - uint32_t irq_level; 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 usb_desc_base_t { - 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 usb_desc_setup_t { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} usb_desc_setup_t; - -typedef struct usb_desc_endpoint_t { - 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_hid_t { - 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_interface_t { - 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_string_t { - usb_desc_base_t base; - uint16_t bString[]; -} usb_desc_string_t; - -typedef struct usb_desc_conf_t { - 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_device_t { - 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 efc6fbb6f..4d7483f30 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -15,40 +15,66 @@ * * 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]; + 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; struct { uint16_t subsys_cntl; uint16_t setup_md; - uint8_t advfunc_cntl; + uint16_t advfunc_cntl; uint8_t ext_advfunc_cntl; uint16_t cur_y; - uint16_t cur_y_bitres; uint16_t cur_x; - uint16_t cur_x_bitres; + int16_t destx; + int16_t desty; int16_t desty_axstp; int16_t destx_distp; int16_t err_term; int16_t maj_axis_pcnt; + int16_t maj_axis_pcnt_no_limit; uint16_t cmd; uint16_t cmd_back; uint16_t short_stroke; @@ -75,7 +101,9 @@ typedef struct ibm8514_t { int sys_cnt2; int temp_cnt; int16_t cx; + int16_t cx_back; int16_t cy; + int16_t oldcx; int16_t oldcy; int16_t sx; int16_t sy; @@ -83,11 +111,11 @@ typedef struct ibm8514_t { int16_t dy; int16_t err; uint32_t src; - uint16_t dest; + uint32_t dest; uint32_t newsrc_blt; - uint16_t newdest_blt; + uint32_t newdest_blt; uint32_t newdest_in; - uint16_t newdest_out; + uint32_t newdest_out; uint8_t *writemono; uint8_t *nibbleset; int x_count; @@ -108,11 +136,12 @@ typedef struct ibm8514_t { 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 v_total; int dispend; @@ -143,7 +172,7 @@ typedef struct ibm8514_t { uint8_t *vram; uint8_t *changedvram; - uint8_t linedbl; + uint8_t linedbl; uint8_t data_available; uint8_t data_available2; @@ -177,4 +206,5 @@ typedef struct ibm8514_t { int ext_pitch; int ext_crt_pitch; } ibm8514_t; + #endif /*VIDEO_8514A_H*/ diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index 414460acc..5b6a2dea2 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -66,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 3c7916034..291145291 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 51b735ec7..5acd4c8a2 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 97a08b583..ec241d613 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -44,9 +44,9 @@ typedef struct ega_t { uint8_t colournocare; uint8_t scrblank; uint8_t plane_mask; - uint8_t pad; - uint8_t pad0; - uint8_t pad1; + uint8_t ctl_mode; + uint8_t color_mux; + uint8_t dot; uint8_t crtc[32]; uint8_t gdcreg[16]; uint8_t attrregs[32]; @@ -108,6 +108,9 @@ typedef struct ega_t { int res_y; int bpp; int index; + int remap_required; + int actual_type; + int chipset; uint32_t charseta; uint32_t charsetb; @@ -117,21 +120,24 @@ typedef struct ega_t { uint32_t ca; uint32_t vram_limit; uint32_t overscan_color; + uint32_t cca; uint32_t *pallook; uint64_t dispontime; uint64_t dispofftime; + + uint64_t dot_time; + pc_timer_t timer; + pc_timer_t dot_timer; - double clock; + double dot_clock; - int remap_required; - uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); + void * eeprom; - void (*render)(struct ega_t *svga); - - void *eeprom; + uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); + void (*render)(struct ega_t *svga); } ega_t; #endif @@ -139,7 +145,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 diff --git a/src/include/86box/vid_ega_render_remap.h b/src/include/86box/vid_ega_render_remap.h index 37f6904db..b01bb2b0e 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 b5ba6af9f..c58a50aa3 100644 --- a/src/include/86box/vid_hercules.h +++ b/src/include/86box/vid_hercules.h @@ -40,19 +40,19 @@ typedef struct { int firstline; int lastline; - int linepos; - int displine; - int vc; - int sc; + 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 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 37a4f6b21..d13c45a28 100644 --- a/src/include/86box/vid_mda.h +++ b/src/include/86box/vid_mda.h @@ -21,6 +21,7 @@ typedef struct mda_t { int firstline; int lastline; + int fontbase; int linepos; int displine; int vc; @@ -52,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 93786b15e..bbb5b3c95 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 6b80f5859..839769e69 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 a59ca3d8e..35e2d9e42 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 { @@ -71,10 +71,12 @@ 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 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; + uint32_t screenh; int16_t pan_x; int16_t pan_y; uint16_t win_x1; @@ -156,12 +158,12 @@ 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); #if 0 -extern int pgc_input_byte(pgc_t *, uint8_t *val); -extern int pgc_output_byte(pgc_t *, uint8_t val); +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); #if 0 -extern int pgc_error_byte(pgc_t *, uint8_t val); +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 2fc877f16..7ba637167 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,7 +26,7 @@ # define FLAG_NOSKEW 16 # define FLAG_ADDR_BY16 32 # define FLAG_RAMDAC_SHIFT 64 -# define FLAG_ATI 128 +# define FLAG_ATI 128 # define FLAG_S3_911_16BIT 256 # define FLAG_512K_MASK 512 struct monitor_t; @@ -58,8 +53,6 @@ typedef union { } latch_t; typedef struct svga_t { - ibm8514_t dev8514; - xga_t xga; mem_mapping_t mapping; uint8_t fast; @@ -89,6 +82,7 @@ typedef struct svga_t { int dac_pos; int dac_r; int dac_g; + int dac_b; int vtotal; int dispend; int vsyncstart; @@ -134,6 +128,8 @@ typedef struct svga_t { int hblank_sub; int hblank_end_val; int hblank_end_len; + 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 @@ -144,24 +140,24 @@ 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; - 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 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]; + uint32_t pallook[512]; PALETTE vgapal; @@ -181,10 +177,11 @@ typedef struct svga_t { 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); @@ -195,7 +192,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 @@ -205,17 +202,17 @@ 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 *priv; - uint8_t crtc[256]; - uint8_t gdcreg[256]; - uint8_t attrregs[32]; - uint8_t seqregs[256]; - uint8_t egapal[16]; + 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; @@ -236,6 +233,7 @@ typedef struct svga_t { 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]; @@ -251,6 +249,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; @@ -266,55 +269,63 @@ typedef struct svga_t { uint8_t monitor_index; /* Pointer to monitor */ - monitor_t* monitor; + monitor_t *monitor; + + /* Enable LUT mapping of >= 24 bpp modes. */ + int lut_map; + + /* 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 * 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 ibm8514_poll(void *priv, svga_t *svga); +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); -extern void xga_poll(xga_t *xga, svga_t *svga); +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); +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 *p); +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); @@ -332,70 +343,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 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 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 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 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 *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; @@ -409,6 +428,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 1f587d4f5..33bb13bbf 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -34,44 +34,55 @@ 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_incompatible_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_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 08a1a2591..bc552b285 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_blitter.h b/src/include/86box/vid_voodoo_blitter.h index 981c0856d..261352157 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_common.h b/src/include/86box/vid_voodoo_common.h index 92c608789..96865ac6d 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,8 +587,7 @@ typedef struct voodoo_t { int line_bit_mask_size; } banshee_blt; - struct - { + struct { uint32_t vidOverlayStartCoords; uint32_t vidOverlayEndScreenCoords; uint32_t vidOverlayDudx; @@ -669,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 25b3e9b1a..f046263bf 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 3580cada2..51ec91f2e 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 2138e83da..8a59b30ef 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 0073a295c..e78d0dd6b 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 62738a8c5..3dff4498c 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 65eec54e4..6f325426a 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 af5191a81..e5248b309 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -14,7 +14,6 @@ * * Copyright 2022 TheCollector1995. */ - #ifndef VIDEO_XGA_H #define VIDEO_XGA_H @@ -36,12 +35,13 @@ typedef struct xga_t { mem_mapping_t linear_mapping; mem_mapping_t video_mapping; rom_t bios_rom; - rom_t vga_bios_rom; + rom_t vga_bios_rom; xga_hwcursor_t hwcursor; xga_hwcursor_t hwcursor_latch; PALETTE extpal; uint8_t test; + uint8_t test2; uint8_t atest[2]; uint8_t testpixel; @@ -79,6 +79,7 @@ typedef struct xga_t { uint8_t pal_b_prefetch; uint8_t sprite_data[1024]; uint8_t scrollcache; + uint8_t border_color; uint8_t direct_color; uint8_t dma_channel; uint8_t instance_isa; @@ -156,10 +157,10 @@ typedef struct xga_t { uint32_t rom_addr; uint32_t ma; uint32_t maback; - uint32_t extpallook[256]; uint32_t read_bank; uint32_t write_bank; uint32_t px_map_base; + uint32_t pallook[512]; uint64_t dispontime; uint64_t dispofftime; @@ -199,6 +200,8 @@ typedef struct xga_t { int dst_map; int bkgd_src; int fore_src; + int oldx; + int oldy; int x; int y; int sx; @@ -209,6 +212,7 @@ typedef struct xga_t { int py; int pattern; int command_len; + int filling; uint32_t short_stroke; uint32_t color_cmp; @@ -225,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 7aa274d30..e337ef9d3 100644 --- a/src/include/86box/vid_xga_device.h +++ b/src/include/86box/vid_xga_device.h @@ -17,7 +17,6 @@ #ifndef VIDEO_XGA_DEVICE_H #define VIDEO_XGA_DEVICE_H -extern int xga_has_vga; #ifdef EMU_DEVICE_H extern const device_t xga_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 4a70f06cb..2d6c884cd 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 @@ -103,8 +107,8 @@ typedef struct monitor_t { int mon_efscrnsz_y; int mon_unscaled_size_x; int mon_unscaled_size_y; - int mon_res_x; - int mon_res_y; + double mon_res_x; + double mon_res_y; int mon_bpp; bitmap_t *target_buffer; int mon_video_timing_read_b; @@ -152,7 +156,7 @@ extern int changeframecount; extern volatile int screenshots; #if 0 -extern bitmap_t *buffer32; +extern bitmap_t *buffer32; #endif #define buffer32 (monitors[monitor_index_global].target_buffer) #define pal_lookup (monitors[monitor_index_global].mon_pal_lookup) @@ -179,13 +183,15 @@ extern bitmap_t *buffer32; extern PALETTE cgapal; extern PALETTE cgapal_mono[6]; #if 0 -extern uint32_t pal_lookup[256]; +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]; @@ -208,7 +214,8 @@ extern double cpuclock; extern int emu_fps; extern int frames; extern int readflash; -extern int ibm8514_has_vga; +extern int ibm8514_active; +extern int xga_active; /* Function handler pointers. */ extern void (*video_recalctimings)(void); @@ -228,17 +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 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 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); @@ -263,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); @@ -300,7 +309,9 @@ extern void ibm8514_device_add(void); extern const device_t mach8_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; @@ -348,7 +359,9 @@ 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; @@ -422,12 +435,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; @@ -478,6 +491,7 @@ extern const device_t s3_phoenix_trio64_onboard_pci_device; extern const device_t s3_phoenix_trio64_pci_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; diff --git a/src/include/86box/zip.h b/src/include/86box/zip.h index 9ff69d092..a4a4c341f 100644 --- a/src/include/86box/zip.h +++ b/src/include/86box/zip.h @@ -29,6 +29,8 @@ #define ZIP_250_SECTORS (489532) +#define ZIP_IMAGE_HISTORY 4 + enum { ZIP_BUS_DISABLED = 0, ZIP_BUS_ATAPI = 5, @@ -55,12 +57,14 @@ typedef struct zip_drive_t { uint8_t pad; uint8_t pad0; - FILE *f; + FILE *fp; void *priv; char image_path[1024]; char prev_image_path[1024]; + char *image_history[ZIP_IMAGE_HISTORY]; + uint32_t is_250; uint32_t medium_size; uint32_t base; @@ -70,23 +74,35 @@ 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; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; - uint8_t status; - uint8_t phase; - uint8_t error; - uint8_t id; +#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 id; uint8_t cur_lun; uint8_t pad0; uint8_t pad1; - uint16_t request_length; uint16_t max_transfer_len; + uint16_t pad2; int requested_blocks; int packet_status; @@ -100,7 +116,6 @@ typedef struct zip_t { uint32_t sector_pos; uint32_t sector_len; uint32_t packet_len; - uint32_t pos; double callback; } zip_t; diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index 96e81ce5f..4004f58b3 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -22,11 +22,11 @@ #define EMU_NAME "86Box" #define EMU_NAME_W LSTR(EMU_NAME) -#define EMU_VERSION "4.0" +#define EMU_VERSION "4.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_MIN 1 #define EMU_VERSION_PATCH 0 #define EMU_BUILD_NUM 0 @@ -34,7 +34,7 @@ #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 29f8e05fb..a792d356b 100644 --- a/src/ini.c +++ b/src/ini.c @@ -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 @@ -560,6 +560,46 @@ 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) { @@ -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 173e6707b..0e68049c3 100644 --- a/src/io.c +++ b/src/io.c @@ -286,16 +286,22 @@ inb(uint16_t port) io_t *p; io_t *q; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif - if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { - ret = pci_type2_read(port, NULL); + 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; - } else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) { - ret = pci_type2_read(port, NULL); +#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) { @@ -303,7 +309,9 @@ inb(uint16_t port) if (p->inb) { ret &= p->inb(port, p->priv); found |= 1; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -338,16 +346,22 @@ outb(uint16_t port, uint8_t val) io_t *p; io_t *q; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif - if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { - pci_type2_write(port, val, NULL); + 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; - } else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) { - pci_type2_write(port, val, NULL); +#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) { @@ -355,7 +369,9 @@ outb(uint16_t port, uint8_t val) if (p->outb) { p->outb(port, val, p->priv); found |= 1; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -381,17 +397,23 @@ 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]; - if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { - ret = pci_type2_readw(port, NULL); + 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; - } else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) { - ret = pci_type2_readw(port, NULL); +#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) { @@ -399,7 +421,9 @@ inw(uint16_t port) if (p->inw) { ret &= p->inw(port, p->priv); found |= 2; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -413,7 +437,9 @@ inw(uint16_t port) if (p->inb && !p->inw) { ret8[i] &= p->inb(port + i, p->priv); found |= 1; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -444,16 +470,22 @@ outw(uint16_t port, uint16_t val) io_t *p; io_t *q; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif - if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { - pci_type2_writew(port, val, NULL); + 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; - } else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) { - pci_type2_writew(port, val, NULL); +#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) { @@ -461,7 +493,9 @@ outw(uint16_t port, uint16_t val) if (p->outw) { p->outw(port, val, p->priv); found |= 2; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -473,7 +507,9 @@ outw(uint16_t port, uint16_t val) if (p->outb && !p->outw) { p->outb(port + i, val >> (i << 3), p->priv); found |= 1; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -502,16 +538,22 @@ inl(uint16_t port) uint16_t ret16[2]; uint8_t ret8[4]; int found = 0; +#ifdef ENABLE_IO_LOG int qfound = 0; +#endif - if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { - ret = pci_type2_readl(port, NULL); + 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; - } else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) { - ret = pci_type2_readl(port, NULL); +#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) { @@ -519,7 +561,9 @@ inl(uint16_t port) if (p->inl) { ret &= p->inl(port, p->priv); found |= 4; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -532,7 +576,9 @@ inl(uint16_t port) if (p->inw && !p->inl) { ret16[0] &= p->inw(port, p->priv); found |= 2; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -543,7 +589,9 @@ inl(uint16_t port) if (p->inw && !p->inl) { ret16[1] &= p->inw(port + 2, p->priv); found |= 2; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -560,7 +608,9 @@ inl(uint16_t port) 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; } @@ -591,17 +641,23 @@ 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; - if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) { - pci_type2_writel(port, val, NULL); + 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; - } else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) { - pci_type2_writel(port, val, NULL); +#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) { @@ -610,7 +666,9 @@ outl(uint16_t port, uint32_t val) if (p->outl) { p->outl(port, val, p->priv); found |= 4; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -623,7 +681,9 @@ outl(uint16_t port, uint32_t val) if (p->outw && !p->outl) { p->outw(port + i, val >> (i << 3), p->priv); found |= 2; +#ifdef ENABLE_IO_LOG qfound++; +#endif } p = q; } @@ -636,7 +696,9 @@ outl(uint16_t port, uint32_t val) 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; } diff --git a/src/lpt.c b/src/lpt.c index 7eb96a278..5bbf79875 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -45,22 +45,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 +68,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++; @@ -165,6 +165,20 @@ lpt_read(uint16_t port, void *priv) 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) { diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 543ebfc11..4bc53c9b4 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -152,8 +152,6 @@ typedef struct amstrad_t { pc_timer_t send_delay_timer; /* Mouse stuff. */ - uint8_t mousex; - uint8_t mousey; int oldb; /* Video stuff. */ @@ -1301,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, &((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++; } } @@ -1692,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, @@ -2007,40 +2006,38 @@ const device_t vid_pc3086_device = { }; static void -ms_write(uint16_t addr, UNUSED(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, UNUSED(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); @@ -2602,10 +2599,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_286_386sx.c b/src/machine/m_at_286_386sx.c index fb87c9976..79a82595f 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. */ @@ -350,6 +348,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) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index d18f29993..8c06fc815 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 @@ -404,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; } @@ -686,18 +683,27 @@ machine_at_pc330_6573_init(const machine_t *model) /* doesn't like every CPU oth if (bios_only || !ret) return ret; - machine_at_common_init(model); + 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(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(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); - device_add(&opti802g_pci_device); + 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_device); - device_add(&fdc37c665_device); + device_add(&keyboard_ps2_ami_device); + device_add(&fdc37c665_ide_device); device_add(&ide_opti611_vlb_device); device_add(&intel_flash_bxt_device); @@ -1849,11 +1855,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); @@ -1889,7 +1895,7 @@ 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; } @@ -2069,7 +2075,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; } @@ -2091,7 +2097,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); @@ -2125,7 +2131,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); diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 0731aa810..86656b181 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -31,6 +31,7 @@ #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> @@ -51,7 +52,7 @@ enum { COMPAQ_PORTABLEIII, COMPAQ_PORTABLEIII386, COMPAQ_DESKPRO386, - COMPAQ_DESKPRO386_01_1988 + COMPAQ_DESKPRO386_05_1988 }; #define CGA_RGB 0 @@ -279,7 +280,7 @@ compaq_plasma_poll(void *priv) uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black; uint32_t bg = black; uint32_t cols[2]; - uint8_t dat2; + uint8_t dat; uint8_t pattern; uint32_t ink0 = 0; uint32_t ink1 = 0; @@ -314,25 +315,25 @@ compaq_plasma_poll(void *priv) addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); } for (uint8_t x = 0; x < 80; x++) { - dat2 = self->cga.vram[addr & 0x7FFF]; + dat = self->cga.vram[addr & 0x7FFF]; addr++; for (uint8_t c = 0; c < 8; c++) { - ink = (dat2 & 0x80) ? fg : bg; + ink = (dat & 0x80) ? fg : bg; if (!(self->cga.cgamode & 8)) ink = black; (buffer32->line[self->cga.displine])[x * 8 + c] = ink; - dat2 <<= 1; + dat <<= 1; } } } else { addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); for (uint8_t x = 0; x < 80; x++) { - dat2 = self->cga.vram[addr & 0x7fff]; + dat = self->cga.vram[addr & 0x7fff]; addr++; for (uint8_t c = 0; c < 4; c++) { - pattern = (dat2 & 0xC0) >> 6; + pattern = (dat & 0xC0) >> 6; if (!(self->cga.cgamode & 8)) pattern = 0; @@ -367,7 +368,7 @@ compaq_plasma_poll(void *priv) } buffer32->line[self->cga.displine][x * 8 + 2 * c] = ink0; buffer32->line[self->cga.displine][x * 8 + 2 * c + 1] = ink1; - dat2 <<= 2; + dat <<= 2; } } } @@ -385,34 +386,25 @@ compaq_plasma_poll(void *priv) /* for each text column */ for (uint8_t x = 0; x < 80; x++) { /* video output enabled */ - if (self->cga.cgamode & 8) { - chr = self->cga.vram[(addr + 2 * x) & 0x7fff]; - attr = self->cga.vram[(addr + 2 * x + 1) & 0x7fff]; - } else - chr = attr = 0; - /* check if cursor has to be drawn */ - drawcursor = ((ma == ca) && cursorline && self->cga.cursoron); + chr = self->cga.vram[(addr + 2 * x) & 0x7FFF]; + attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF]; + drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); + + blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); - if (underline) { - /* set forecolor to white */ - attr |= 7; - } - blink = 0; /* blink active */ if (self->cga.cgamode & 0x20) { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; /* attribute 7 active and not cursor */ - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) { + if (blink) { /* set blinking */ cols[1] = cols[0]; - blink = 1; } } else { /* Set intensity bit */ cols[1] = normcols[attr][1]; cols[0] = normcols[attr][0]; - blink = (attr & 0x80) * 8 + 7 + 16; } /* character underline active and 7th row of pixels in character height being drawn */ if (underline && (sc == 7)) { @@ -421,10 +413,10 @@ compaq_plasma_poll(void *priv) buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1]; } else if (drawcursor) { for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); } else { for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; } ++ma; @@ -440,34 +432,25 @@ compaq_plasma_poll(void *priv) cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc); for (uint8_t x = 0; x < 40; x++) { - if (self->cga.cgamode & 8) { - chr = self->cga.vram[(addr + 2 * x) & 0x7fff]; - attr = self->cga.vram[(addr + 2 * x + 1) & 0x7fff]; - } else { - chr = attr = 0; - } - drawcursor = ((ma == ca) && cursorline && self->cga.cursoron); + chr = self->cga.vram[(addr + 2 * x) & 0x7FFF]; + attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF]; + drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); + + blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); - if (underline) { - /* set forecolor to white */ - attr |= 7; - } - blink = 0; /* blink active */ if (self->cga.cgamode & 0x20) { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; /* attribute 7 active and not cursor */ - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) { + if (blink) { /* set blinking */ cols[1] = cols[0]; - blink = 1; } } else { /* Set intensity bit */ cols[1] = normcols[attr][1]; cols[0] = normcols[attr][0]; - blink = (attr & 0x80) * 8 + 7 + 16; } /* character underline active and 7th row of pixels in character height being drawn */ if (underline && (sc == 7)) { @@ -475,13 +458,11 @@ compaq_plasma_poll(void *priv) for (uint8_t c = 0; c < 8; c++) buffer32->line[self->cga.displine][(x << 4) + (c * 2)] = buffer32->line[self->cga.displine][(x << 4) + (c * 2) + 1] = mdaattr[attr][blink][1]; } else if (drawcursor) { - for (uint8_t c = 0; c < 8; c++) { - buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); } else { - for (uint8_t c = 0; c < 8; c++) { - buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } + for (uint8_t c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; } ++ma; } @@ -652,7 +633,7 @@ compaq_plasma_init(UNUSED(const device_t *info)) memset(self, 0, sizeof(compaq_plasma_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma); - loadfont_ex("roms/machines/portableiii/K Combined.bin", 1, 0x4bb2); + loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2); self->cga.composite = 0; self->cga.revision = 0; @@ -704,8 +685,8 @@ const device_config_t compaq_plasma_config[] = { // clang-format off { .name = "rgb_type", - .description = "RGB type", - .type = CONFIG_SELECTION, + .description = "RGB type", + .type = CONFIG_SELECTION, .default_string = "", .default_int = 0, .file_filter = "", @@ -795,34 +776,28 @@ machine_at_compaq_init(const machine_t *model, int type) { compaq_machine_type = type; - if ((type != COMPAQ_DESKPRO386) && (type != COMPAQ_DESKPRO386_01_1988)) - mem_remap_top(384); - if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - if ((type == COMPAQ_DESKPRO386) || (type == COMPAQ_DESKPRO386_01_1988) || (type == COMPAQ_PORTABLEIII386)) - mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, - read_ram, read_ramw, read_raml, - write_ram, write_ramw, write_raml, - 0xa0000 + ram, MEM_MAPPING_EXTERNAL, NULL); - else + 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); + machine_at_init(model); break; case COMPAQ_PORTABLEIII: if (gfxcard[0] == VID_INTERNAL) device_add(&compaq_plasma_device); - machine_at_init(model); + machine_at_init(model); break; case COMPAQ_PORTABLEIII386: @@ -830,13 +805,14 @@ machine_at_compaq_init(const machine_t *model, int type) device_add(&ide_isa_device); if (gfxcard[0] == VID_INTERNAL) device_add(&compaq_plasma_device); - machine_at_init(model); + machine_at_init(model); break; case COMPAQ_DESKPRO386: - case COMPAQ_DESKPRO386_01_1988: + case COMPAQ_DESKPRO386_05_1988: if (hdc_current == 1) device_add(&ide_isa_device); + device_add(&compaq_386_device); machine_at_common_init(model); device_add(&keyboard_at_compaq_device); break; @@ -913,17 +889,17 @@ machine_at_deskpro386_init(const machine_t *model) } int -machine_at_deskpro386_01_1988_init(const machine_t *model) +machine_at_deskpro386_05_1988_init(const machine_t *model) { int ret; - ret = bios_load_linearr("roms/machines/deskpro386/1988-01-28.json.bin", + 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_01_1988); + 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 71c9d2ab7..d4264f07e 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 184cfc34d..83e9b74a9 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -152,6 +152,43 @@ machine_at_spitfire_init(const machine_t *model) return ret; } +int +machine_at_mate_nx_ma30d_23d_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/mate_nx_ma30d_23d/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, 0xF, 256); + device_add(&lm78_device); /* no reporting in BIOS */ + + return ret; +} + int machine_at_p6i440e2_init(const machine_t *model) { @@ -223,6 +260,37 @@ machine_at_p2bls_init(const machine_t *model) return ret; } +int +machine_at_lgibm440bx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/lgibm440bx/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) { diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index fd91067ae..da160c138 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 b8cc437a1..2b2615422 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -1,458 +1,497 @@ -/* - * 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); + + 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); + 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 b8e080d62..a32617de4 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 @@ -269,6 +267,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); @@ -280,6 +279,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; } @@ -288,8 +290,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) diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 9a45e71bf..0b67976af 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) { @@ -160,6 +177,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 +222,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); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 3c0f0481a..a3e777dbd 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. * */ @@ -174,6 +171,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 +222,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 +233,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 +261,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 +272,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,7 +285,83 @@ machine_at_infinia7200_init(const machine_t *model) return ret; } -/* Information about that machine on machine.h */ +static void +machine_at_cu430hx_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; + + if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)->available()) + gpio |= 0xffff04ff; + + machine_set_gpio_default(gpio); +} + +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); // 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) { @@ -260,21 +377,7 @@ machine_at_equium5200_init(const machine_t *model) 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(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 - 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); + machine_at_cu430hx_common_init(model); return ret; } @@ -294,7 +397,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); @@ -550,7 +654,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 +664,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); @@ -978,9 +1087,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 +1116,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 +1134,35 @@ machine_at_ms5146_init(const machine_t *model) return ret; } +int +machine_at_cb52x_si_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/cb52x_si/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_m560_init(const machine_t *model) { @@ -1088,3 +1226,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 852ce0a55..0e420aa3b 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,12 +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)); -#if 0 - device_add(&keyboard_ps2_ami_pci_device); -#endif device_add(&keyboard_ps2_intel_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); @@ -180,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; } @@ -196,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; } @@ -213,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); @@ -225,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); @@ -241,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) @@ -265,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) { @@ -276,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); @@ -458,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); @@ -505,6 +671,40 @@ machine_at_p5vxb_init(const machine_t *model) return ret; } +int +machine_at_dell_430vx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/dell_430vx/1003DY0J.BIO", + "roms/machines/dell_430vx/1003DY0J.BI1", + "roms/machines/dell_430vx/1003DY0J.BI2", + "roms/machines/dell_430vx/1003DY0J.BI3", + "roms/machines/dell_430vx/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) { @@ -528,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); @@ -550,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); @@ -579,19 +779,19 @@ machine_at_ms5124_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1); + pci_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; diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index c1c95f197..6e63af732 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -54,14 +54,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 +161,35 @@ machine_at_acerv60n_init(const machine_t *model) return ret; } +int +machine_at_lgibm440fx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/lgibm440fx/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(&w83787f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_vs440fx_init(const machine_t *model) { @@ -195,6 +224,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 dab544707..382a4f327 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 diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index a84845982..e3e24cf2c 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 diff --git a/src/machine/m_at_t3100e_vid.c b/src/machine/m_at_t3100e_vid.c index 57b0641a6..50c9ec05a 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 diff --git a/src/machine/m_elt.c b/src/machine/m_elt.c index c1aa6396b..95ca52a3e 100644 --- a/src/machine/m_elt.c +++ b/src/machine/m_elt.c @@ -50,6 +50,7 @@ #include <86box/rom.h> #include <86box/video.h> #include <86box/vid_cga.h> +#include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> static void @@ -123,9 +124,7 @@ elt_vid_out(uint16_t addr, uint8_t val, void *priv) case 0x3d1: if (cga->crtcreg >= 32) return; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; default: cga->crtcreg &= 31; diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index f8c50a931..80a0ffbc1 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -122,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]; } } @@ -160,11 +168,17 @@ vid_out(uint16_t addr, uint8_t val, void *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) { @@ -190,6 +204,10 @@ vid_out(uint16_t addr, uint8_t val, void *priv) 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; @@ -206,11 +224,17 @@ vid_in(uint16_t addr, void *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; @@ -591,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); @@ -647,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 @@ -810,6 +834,8 @@ machine_pcjr_init(UNUSED(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); @@ -853,7 +879,10 @@ machine_pcjr_init(UNUSED(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_hdc.c b/src/machine/m_ps1_hdc.c index 07969f1c8..f35879458 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 { @@ -380,7 +380,6 @@ typedef struct hdc_t { 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 */ int8_t reset; /* reset state counter */ @@ -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) @@ -633,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; @@ -653,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: @@ -665,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: @@ -699,9 +683,7 @@ do_fmt: /* Done with this track. */ dev->state = STATE_FDONE; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case STATE_FDONE: /* One more track done. */ if (++start_cyl == end_cyl) { @@ -739,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; @@ -760,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) { @@ -790,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. */ @@ -814,12 +796,12 @@ do_send: 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); @@ -854,7 +836,7 @@ do_send: } } dev->state = STATE_SDONE; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); break; case STATE_SDONE: @@ -882,7 +864,6 @@ do_send: } break; - case CMD_READ_EXT: /* READ_EXT */ case CMD_READ_ID: /* READ_ID */ if (!drive->present) { dev->ssb.not_ready = 1; @@ -890,6 +871,56 @@ do_send: 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; @@ -907,7 +938,7 @@ do_send: case CMD_WRITE_VERIFY: no_data = 1; - /*FALLTHROUGH*/ + fallthrough; case CMD_WRITE_SECTORS: if (!drive->present) { @@ -934,7 +965,7 @@ do_send: dev->buf_len = (128 << dev->ssb.sect_size); dev->state = STATE_RECV; - /*FALLTHROUGH*/ + fallthrough; case STATE_RECV: /* Activate the status icon. */ @@ -945,12 +976,12 @@ do_recv: 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; @@ -980,7 +1011,7 @@ do_recv: } } dev->state = STATE_RDONE; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); break; case STATE_RDONE: @@ -1142,6 +1173,8 @@ hdc_read(uint16_t port, void *priv) break; } + ps1_hdc_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); + return ret; } @@ -1150,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; @@ -1166,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; @@ -1184,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); } } } diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index b93f332db..a6fc30e1c 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -362,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); @@ -499,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); @@ -563,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); @@ -621,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); @@ -985,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; @@ -1005,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) { @@ -1051,10 +1056,8 @@ ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots) 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; @@ -1312,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 is486ps2) +ps2_mca_board_model_80_type2_init(void) { ps2_mca_board_common_init(); @@ -1372,7 +1375,7 @@ ps2_mca_board_model_80_type2_init(int is486ps2) NULL); mem_mapping_disable(&ps2.split_mapping); - if ((mem_size > 4096) && !is486ps2) { + 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); @@ -1426,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; } @@ -1448,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; } @@ -1509,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; @@ -1530,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; } @@ -1550,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; @@ -1571,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 5784eb4df..1d4c3303f 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -128,6 +128,7 @@ typedef struct tandy_t { int rom_offset; /* SL2 */ uint32_t base; + uint32_t mask; int is_sl2; t1kvid_t *vid; @@ -1238,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)); @@ -1256,11 +1257,11 @@ eep_init(const device_t *info) 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); @@ -1273,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); @@ -1319,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; @@ -1378,7 +1390,7 @@ write_ram(uint32_t addr, uint8_t val, void *priv) { const tandy_t *dev = (tandy_t *) priv; - ram[dev->base + (addr & 0x1ffff)] = val; + ram[dev->base + (addr & dev->mask)] = val; } static uint8_t @@ -1386,7 +1398,7 @@ read_ram(uint32_t addr, void *priv) { const tandy_t *dev = (tandy_t *) priv; - return (ram[dev->base + (addr & 0x1ffff)]); + return (ram[dev->base + (addr & dev->mask)]); } static uint8_t @@ -1462,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); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 84eb517c8..20a7da6ae 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.5_8E.ROM", + 0x000fe000, 8192, 0); + + if (bios_only || !ret) + return ret; + + machine_xt_init_ex(model); + + return ret; +} \ No newline at end of file diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 0a638ce37..0b5a3eab0 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -130,10 +130,9 @@ typedef struct m24_kbd_t { uint8_t scan[7]; /* Mouse stuff. */ - int mouse_mode; - int x; - int y; + int mouse_input_mode; int b; + pc_timer_t send_delay_timer; } m24_kbd_t; @@ -551,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]; @@ -562,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]; @@ -721,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; @@ -732,12 +731,14 @@ m24_kbd_reset(void *priv) } static int -ms_poll(int x, int y, UNUSED(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; @@ -766,57 +767,49 @@ ms_poll(int x, int y, UNUSED(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]); } } @@ -1511,7 +1504,7 @@ m19_vid_init(m19_vid_t *vid) #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"); @@ -1923,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; @@ -1949,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 4caff1431..1fc284a46 100644 --- a/src/machine/m_xt_philips.c +++ b/src/machine/m_xt_philips.c @@ -91,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 diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 2880f4201..a12fa4e96 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 @@ -833,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", @@ -856,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, @@ -986,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); } } @@ -1049,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); } } } @@ -1063,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 006698869..4ec13b5c4 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 diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index 628b98e8b..0da091917 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. */ @@ -56,7 +56,8 @@ typedef struct { static uint8_t zenith_scratchpad_read(uint32_t addr, void *priv) { - zenith_t *dev = (zenith_t *) priv; + const zenith_t *dev = (zenith_t *) priv; + return dev->scratchpad_ram[addr & 0x3fff]; } @@ -111,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); @@ -143,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); @@ -170,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; } @@ -190,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 47e98e7b3..1684f312a 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. */ @@ -74,7 +72,15 @@ 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; @@ -108,7 +114,7 @@ machine_init_ex(int m) /* Reset the fast off stuff. */ cpu_fast_off_reset(); - pci_take_over_io = 0x00000000; + pci_flags = 0x00000000; } /* All good, boot the machine! */ @@ -118,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; } @@ -172,13 +168,15 @@ pit_irq0_timer(int new_out, int old_out) void machine_common_init(UNUSED(const machine_t *model)) { + uint8_t cpu_requires_fast_pit = is486 || (!is286 && is8086 && (cpu_s->rspeed >= 8000000)); + /* 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 56d160209..9a14b78b1 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. */ @@ -165,7 +163,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. @@ -209,10 +206,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, @@ -232,8 +229,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, @@ -247,10 +245,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, @@ -270,8 +268,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, @@ -285,10 +284,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, @@ -302,18 +301,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 }, @@ -323,10 +323,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, @@ -346,8 +346,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, @@ -361,10 +362,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, @@ -384,8 +385,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, @@ -399,10 +401,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, @@ -422,8 +424,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, @@ -437,10 +440,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, @@ -460,8 +463,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, @@ -475,10 +479,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, @@ -498,8 +502,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, @@ -513,10 +518,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, @@ -536,8 +541,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, @@ -551,10 +557,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, @@ -574,8 +580,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, @@ -589,10 +596,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, @@ -612,8 +619,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, @@ -627,10 +635,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, @@ -650,8 +658,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, @@ -665,10 +674,10 @@ 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, @@ -688,8 +697,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, @@ -703,10 +713,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, @@ -726,8 +736,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, @@ -741,10 +752,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, @@ -764,8 +775,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, @@ -779,10 +791,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, @@ -802,8 +814,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, @@ -817,10 +830,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, @@ -840,8 +853,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, @@ -855,10 +869,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, @@ -878,8 +892,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, @@ -893,10 +908,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_micoms_xl7turbo_init, - .pad = 0, - .pad0 = 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, @@ -916,8 +931,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, @@ -931,10 +947,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_pc500_init, - .pad = 0, - .pad0 = 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, @@ -954,8 +970,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, @@ -969,10 +986,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_xt_pc700_init, - .pad = 0, - .pad0 = 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, @@ -992,8 +1009,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, @@ -1007,10 +1025,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, @@ -1026,12 +1044,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, @@ -1045,10 +1064,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, @@ -1064,16 +1083,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 }, @@ -1083,10 +1103,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, @@ -1106,8 +1126,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, @@ -1121,10 +1142,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, @@ -1140,12 +1161,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, @@ -1159,10 +1181,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, @@ -1182,8 +1204,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, @@ -1197,10 +1220,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, @@ -1220,8 +1243,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, @@ -1235,10 +1259,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, @@ -1258,8 +1282,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, @@ -1273,10 +1298,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, @@ -1292,12 +1317,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, @@ -1311,10 +1337,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, @@ -1334,8 +1360,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, @@ -1349,10 +1376,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, @@ -1372,8 +1399,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, @@ -1387,10 +1415,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, @@ -1410,12 +1438,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 }, @@ -1425,10 +1454,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, @@ -1442,18 +1471,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 }, @@ -1463,10 +1493,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, @@ -1486,12 +1516,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 }, @@ -1501,10 +1532,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, @@ -1524,8 +1555,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, @@ -1540,10 +1572,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, @@ -1563,8 +1595,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, @@ -1580,10 +1613,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, @@ -1603,8 +1636,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, @@ -1618,10 +1652,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, @@ -1641,8 +1675,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, @@ -1656,10 +1691,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, @@ -1679,8 +1714,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, @@ -1694,10 +1730,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, @@ -1717,8 +1753,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, @@ -1732,10 +1769,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, @@ -1755,9 +1792,49 @@ 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 = &cga_device, + .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, + .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, @@ -1770,10 +1847,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, @@ -1793,8 +1870,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, @@ -1808,10 +1886,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), @@ -1831,8 +1909,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, @@ -1848,10 +1927,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, @@ -1871,12 +1950,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 }, @@ -1886,15 +1966,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, @@ -1909,12 +1989,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 }, @@ -1924,15 +2005,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, @@ -1947,12 +2028,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 }, @@ -1962,15 +2044,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, @@ -1985,12 +2067,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 }, @@ -2000,15 +2083,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, @@ -2023,12 +2106,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 }, @@ -2038,15 +2122,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, @@ -2061,12 +2145,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 }, @@ -2076,10 +2161,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, @@ -2099,8 +2184,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, @@ -2114,10 +2200,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, @@ -2137,8 +2223,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, @@ -2152,10 +2239,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, @@ -2175,12 +2262,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 }, @@ -2191,10 +2279,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, @@ -2214,8 +2302,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, @@ -2229,10 +2318,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, @@ -2252,8 +2341,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, @@ -2267,10 +2357,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, @@ -2290,12 +2380,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 }, @@ -2305,10 +2396,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, @@ -2328,12 +2419,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 }, @@ -2343,10 +2435,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, @@ -2366,8 +2458,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, @@ -2383,10 +2476,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, @@ -2406,8 +2499,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, @@ -2425,10 +2519,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, @@ -2448,8 +2542,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, @@ -2464,10 +2559,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, @@ -2487,8 +2582,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, @@ -2503,10 +2599,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, @@ -2526,8 +2622,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, @@ -2542,10 +2639,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, @@ -2565,8 +2662,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, @@ -2581,10 +2679,10 @@ 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, @@ -2604,8 +2702,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, @@ -2621,10 +2720,10 @@ 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, @@ -2644,8 +2743,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, @@ -2660,10 +2760,10 @@ 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, @@ -2683,8 +2783,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, @@ -2699,10 +2800,10 @@ 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, @@ -2722,12 +2823,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 }, @@ -2738,10 +2840,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, @@ -2761,8 +2863,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, @@ -2777,10 +2880,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, @@ -2800,8 +2903,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, @@ -2817,10 +2921,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, @@ -2840,8 +2944,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, @@ -2858,10 +2963,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, @@ -2881,8 +2986,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, @@ -2898,10 +3004,10 @@ 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, @@ -2921,8 +3027,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, @@ -2937,10 +3044,10 @@ 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, @@ -2960,8 +3067,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, @@ -2976,10 +3084,10 @@ 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, @@ -2999,8 +3107,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, @@ -3015,10 +3124,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, @@ -3038,8 +3147,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, @@ -3054,10 +3164,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, @@ -3069,7 +3179,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, @@ -3077,8 +3187,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, @@ -3093,10 +3204,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, @@ -3116,8 +3227,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, @@ -3132,10 +3244,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, @@ -3155,8 +3267,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, @@ -3171,10 +3324,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, @@ -3194,8 +3347,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, @@ -3210,10 +3364,10 @@ const machine_t machines[] = { .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, @@ -3233,8 +3387,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, @@ -3249,10 +3404,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, @@ -3272,8 +3427,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, @@ -3288,10 +3444,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, @@ -3311,8 +3467,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, @@ -3327,10 +3484,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, @@ -3350,8 +3507,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, @@ -3366,10 +3524,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, @@ -3389,8 +3547,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, @@ -3405,10 +3564,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, @@ -3428,8 +3587,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, @@ -3444,10 +3604,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, @@ -3467,8 +3627,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, @@ -3483,10 +3644,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, @@ -3506,8 +3667,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, @@ -3522,10 +3684,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, @@ -3545,8 +3707,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, @@ -3563,10 +3726,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, @@ -3586,8 +3749,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, @@ -3602,10 +3766,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, @@ -3625,8 +3789,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, @@ -3644,10 +3809,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, @@ -3667,8 +3832,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, @@ -3683,10 +3849,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, @@ -3706,8 +3872,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, @@ -3722,10 +3889,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, @@ -3745,8 +3912,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, @@ -3761,10 +3929,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, @@ -3784,8 +3952,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, @@ -3800,10 +3969,10 @@ const machine_t machines[] = { .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, @@ -3823,8 +3992,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, @@ -3841,10 +4011,10 @@ const machine_t machines[] = { .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, @@ -3864,12 +4034,13 @@ 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 }, @@ -3881,10 +4052,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M1217, .init = machine_at_mr1217_init, - .pad = 0, - .pad0 = 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, @@ -3904,8 +4075,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, @@ -3920,10 +4092,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M6117, .init = machine_at_pja511m_init, - .pad = 0, - .pad0 = 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, @@ -3943,8 +4115,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, @@ -3959,10 +4132,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, @@ -3982,8 +4155,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, @@ -4000,10 +4174,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, @@ -4023,12 +4197,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 }, @@ -4041,10 +4216,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, @@ -4064,8 +4239,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, @@ -4079,10 +4255,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, @@ -4102,8 +4278,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, @@ -4120,10 +4297,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, @@ -4143,8 +4320,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, @@ -4159,10 +4337,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, @@ -4182,8 +4360,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, @@ -4198,10 +4377,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, @@ -4221,8 +4400,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, @@ -4239,10 +4419,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, @@ -4262,12 +4442,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 }, @@ -4280,10 +4461,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, @@ -4303,8 +4484,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, @@ -4319,10 +4501,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, @@ -4342,12 +4524,13 @@ 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 }, @@ -4359,10 +4542,10 @@ const machine_t machines[] = { .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, @@ -4382,8 +4565,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, @@ -4398,10 +4582,10 @@ 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, @@ -4421,8 +4605,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, @@ -4439,10 +4624,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, @@ -4462,8 +4647,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, @@ -4478,10 +4664,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, @@ -4501,8 +4687,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, @@ -4520,10 +4707,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, @@ -4543,8 +4730,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, @@ -4560,10 +4748,10 @@ const machine_t machines[] = { .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, @@ -4583,8 +4771,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, @@ -4599,10 +4788,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, @@ -4622,8 +4811,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, @@ -4638,10 +4828,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, @@ -4661,8 +4851,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, @@ -4677,10 +4868,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_deskpro386_init, - .pad = 0, - .pad0 = 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, @@ -4694,14 +4885,15 @@ const machine_t machines[] = { .bus_flags = MACHINE_AT, .flags = MACHINE_IDE, .ram = { - .min = 640, + .min = 1024, .max = 16384, - .step = 128 + .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, @@ -4710,15 +4902,15 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[ISA] Compaq Deskpro 386 (January 1988)", - .internal_name = "deskpro386_01_1988", + .name = "[ISA] Compaq Deskpro 386 (May 1988)", + .internal_name = "deskpro386_05_1988", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_deskpro386_01_1988_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .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, .block = CPU_BLOCK_NONE, @@ -4732,14 +4924,15 @@ const machine_t machines[] = { .bus_flags = MACHINE_AT, .flags = MACHINE_IDE, .ram = { - .min = 640, + .min = 1024, .max = 16384, - .step = 128 + .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, @@ -4753,10 +4946,10 @@ const machine_t machines[] = { .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, @@ -4776,12 +4969,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 }, @@ -4792,10 +4986,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, @@ -4815,8 +5009,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, @@ -4868,10 +5063,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, @@ -4891,8 +5086,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,10 +5105,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, @@ -4932,8 +5128,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, @@ -4951,10 +5148,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_386DX_486, .chipset = MACHINE_CHIPSET_OPTI_495, .init = machine_at_opti495_init, - .pad = 0, - .pad0 = 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_SOCKET1, .block = CPU_BLOCK_NONE, @@ -4974,8 +5171,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, @@ -4990,10 +5188,10 @@ const machine_t machines[] = { .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, + .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, @@ -5013,8 +5211,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, @@ -5029,10 +5228,10 @@ const machine_t machines[] = { .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, + .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, @@ -5052,8 +5251,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, @@ -5068,10 +5268,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, @@ -5091,8 +5291,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, @@ -5107,10 +5308,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, @@ -5130,8 +5331,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, @@ -5152,10 +5354,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, @@ -5175,8 +5377,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, @@ -5193,10 +5396,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, @@ -5216,8 +5419,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, @@ -5233,10 +5437,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, @@ -5256,8 +5460,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, @@ -5272,10 +5477,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, @@ -5295,8 +5500,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, @@ -5311,10 +5517,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, @@ -5334,8 +5540,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, @@ -5351,10 +5558,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, @@ -5374,8 +5581,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,10 +5598,10 @@ const machine_t machines[] = { .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, @@ -5413,8 +5621,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, @@ -5432,10 +5641,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, @@ -5455,8 +5664,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, @@ -5473,10 +5683,10 @@ const machine_t machines[] = { .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, @@ -5496,12 +5706,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 }, @@ -5512,10 +5723,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, @@ -5535,12 +5746,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 }, @@ -5551,13 +5763,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, @@ -5574,8 +5786,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, @@ -5593,10 +5806,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, @@ -5616,8 +5829,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, @@ -5632,10 +5846,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, @@ -5655,12 +5869,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 }, @@ -5671,10 +5886,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, @@ -5694,8 +5909,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, @@ -5710,10 +5926,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_SIS_461, .init = machine_at_decpclpv_init, - .pad = 0, - .pad0 = 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, @@ -5733,12 +5949,13 @@ const machine_t machines[] = { }, .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 = &s3_86c805_onboard_vlb_device, .snd_device = NULL, .net_device = NULL }, @@ -5749,10 +5966,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_SIS_461, .init = machine_at_acerv10_init, - .pad = 0, - .pad0 = 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, @@ -5772,8 +5989,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, @@ -5789,10 +6007,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, @@ -5812,8 +6030,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,10 +6049,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_SIS_471, .init = machine_at_win471_init, - .pad = 0, - .pad0 = 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, @@ -5853,8 +6072,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, @@ -5950,10 +6170,10 @@ const machine_t machines[] = { .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, @@ -5973,8 +6193,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, @@ -5989,10 +6210,10 @@ const machine_t machines[] = { .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, @@ -6012,8 +6233,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, @@ -6028,10 +6250,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, @@ -6051,8 +6273,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, @@ -6067,10 +6290,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, @@ -6090,8 +6313,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, @@ -6145,10 +6369,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, .init = machine_at_vi15g_init, - .pad = 0, - .pad0 = 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, @@ -6168,8 +6392,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, @@ -6184,10 +6409,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, .init = machine_at_vli486sv2g_init, - .pad = 0, - .pad0 = 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, @@ -6207,8 +6432,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, @@ -6223,10 +6449,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, .init = machine_at_dtk486_init, - .pad = 0, - .pad0 = 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, @@ -6246,8 +6472,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, @@ -6262,10 +6489,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, .init = machine_at_ami471_init, - .pad = 0, - .pad0 = 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, @@ -6285,8 +6512,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, @@ -6301,10 +6529,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, .init = machine_at_tg486g_init, - .pad = 0, - .pad0 = 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, @@ -6324,8 +6552,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, @@ -6338,12 +6567,21 @@ const machine_t machines[] = { .name = "[SiS 471] DEC Venturis 4xx", .internal_name = "dvent4xx", .type = MACHINE_TYPE_486_S3, +<<<<<<< HEAD .chipset = MACHINE_CHIPSET_SIS_471, .init = machine_at_dvent4xx_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, .pad2 = 0, +======= + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_ms4134_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, +>>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6363,9 +6601,16 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, +<<<<<<< HEAD .kbc_p1 = 0, .gpio = 0, .device = &s3_phoenix_trio32_onboard_vlb_device, +======= + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, +>>>>>>> origin/master .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -6378,11 +6623,19 @@ const machine_t machines[] = { .internal_name = "ecsal486", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_ALI_M1429G, +<<<<<<< HEAD .init = machine_at_ecsal486_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, .pad2 = 0, +======= + .init = machine_at_tg486gp_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, +>>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6402,8 +6655,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, @@ -6416,12 +6670,21 @@ const machine_t machines[] = { .name = "[ALi M1429G] Lanner Electronics AP-4100AA", .internal_name = "ap4100aa", .type = MACHINE_TYPE_486_S3, +<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_ap4100aa_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, .pad2 = 0, +======= + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_sbc490_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, +>>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6441,12 +6704,18 @@ const machine_t machines[] = { }, .nvrmask = 127, .kbc_device = NULL, +<<<<<<< HEAD .kbc_p1 = 0, .gpio = 0, +======= + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, +>>>>>>> origin/master .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, + .vid_device = &tgui9440_onboard_pci_device, .snd_device = NULL, .net_device = NULL }, @@ -6455,12 +6724,21 @@ const machine_t machines[] = { .name = "[ALi M1429G] A-Trend ATC-1762", .internal_name = "atc1762", .type = MACHINE_TYPE_486_S3, +<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_atc1762_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, .pad2 = 0, +======= + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_abpb4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, +>>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6480,8 +6758,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, @@ -6496,12 +6775,21 @@ const machine_t machines[] = { .name = "[ALi M1429G] MSI MS-4134", .internal_name = "ms4134", .type = MACHINE_TYPE_486_S3, +<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_ms4134_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, .pad2 = 0, +======= + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_win486pci_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, +>>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6521,8 +6809,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, @@ -6535,12 +6824,21 @@ const machine_t machines[] = { .name = "[ALi M1429G] TriGem 486GP", .internal_name = "tg486gp", .type = MACHINE_TYPE_486_S3, +<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_tg486gp_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, .pad2 = 0, +======= + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_ms4145_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, +>>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6560,8 +6858,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, @@ -6575,11 +6874,19 @@ const machine_t machines[] = { .internal_name = "sbc490", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_ALI_M1489, +<<<<<<< HEAD .init = machine_at_sbc490_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, .pad2 = 0, +======= + .init = machine_at_tf486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, +>>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6599,9 +6906,16 @@ const machine_t machines[] = { }, .nvrmask = 255, .kbc_device = NULL, +<<<<<<< HEAD .kbc_p1 = 0, .gpio = 0, .device = &tgui9440_onboard_pci_device, +======= + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, +>>>>>>> origin/master .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -6614,12 +6928,21 @@ const machine_t machines[] = { .name = "[ALi M1489] ABIT AB-PB4", .internal_name = "abpb4", .type = MACHINE_TYPE_486_S3, +<<<<<<< HEAD .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_abpb4_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, .pad2 = 0, +======= + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_pc330_6573_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, +>>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -6834,20 +7157,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 }, @@ -6897,10 +7221,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, @@ -6920,8 +7244,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, @@ -6936,10 +7261,10 @@ 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, @@ -6959,8 +7284,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, @@ -7092,10 +7418,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, @@ -7115,8 +7441,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, @@ -7131,10 +7458,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, @@ -7154,8 +7481,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, @@ -7210,10 +7538,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_INTEL_420ZX, .init = machine_at_486sp3g_init, - .pad = 0, - .pad0 = 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, @@ -7233,8 +7561,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, @@ -7249,10 +7578,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_IMS_8848, .init = machine_at_pci400cb_init, - .pad = 0, - .pad0 = 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, @@ -7272,8 +7601,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, @@ -7288,10 +7618,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_IMS_8848, .init = machine_at_g486ip_init, - .pad = 0, - .pad0 = 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, @@ -7311,8 +7641,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, @@ -7327,10 +7658,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, @@ -7350,8 +7681,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, @@ -7366,10 +7698,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, @@ -7389,8 +7721,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, @@ -7405,10 +7738,10 @@ const machine_t machines[] = { .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, @@ -7428,8 +7761,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, @@ -7444,10 +7778,10 @@ const machine_t machines[] = { .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, @@ -7467,8 +7801,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, @@ -7484,10 +7819,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), @@ -7501,14 +7836,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, @@ -7524,10 +7860,10 @@ const machine_t machines[] = { .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, @@ -7541,14 +7877,15 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI, .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, @@ -7602,10 +7939,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, @@ -7625,8 +7962,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, @@ -7641,10 +7979,10 @@ const machine_t machines[] = { .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, @@ -7655,7 +7993,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, @@ -7664,8 +8002,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, @@ -7680,10 +8019,10 @@ const machine_t machines[] = { .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, @@ -7703,8 +8042,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, @@ -7760,10 +8100,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, @@ -7783,8 +8123,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, @@ -7799,10 +8140,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, @@ -7822,8 +8163,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, @@ -7837,11 +8179,19 @@ const machine_t machines[] = { .internal_name = "hot433a", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_UMC_UM8881, +<<<<<<< HEAD .init = machine_at_hot433a_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, .pad2 = 0, +======= + .init = machine_at_hot433_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, +>>>>>>> origin/master .cpu = { .package = CPU_PKG_SOCKET3, .block = CPU_BLOCK_NONE, @@ -7861,8 +8211,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, @@ -7877,10 +8228,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, @@ -7900,8 +8251,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, @@ -7916,10 +8268,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, @@ -7939,8 +8291,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, @@ -7959,10 +8312,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, @@ -7982,8 +8335,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, @@ -7999,10 +8353,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, @@ -8022,8 +8376,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, @@ -8039,10 +8394,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, @@ -8062,8 +8417,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, @@ -8119,10 +8475,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, @@ -8142,8 +8498,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, @@ -8159,10 +8516,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, @@ -8182,8 +8539,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, @@ -8205,10 +8563,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, @@ -8228,8 +8586,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, @@ -8244,10 +8603,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, @@ -8267,8 +8626,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, @@ -8283,10 +8643,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, @@ -8306,8 +8666,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, @@ -8322,10 +8683,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, @@ -8345,8 +8706,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, @@ -8363,10 +8725,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, @@ -8386,8 +8748,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, @@ -8402,10 +8765,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, @@ -8417,7 +8780,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 | MACHINE_ACPI, .ram = { .min = 2048, .max = 131072, @@ -8425,12 +8788,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 }, @@ -8441,10 +8805,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, @@ -8464,8 +8828,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, @@ -8480,10 +8845,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, .init = machine_at_586mc1_init, - .pad = 0, - .pad0 = 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, @@ -8503,8 +8868,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, @@ -8519,10 +8885,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, @@ -8542,12 +8908,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 }, @@ -8562,10 +8929,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, @@ -8585,8 +8952,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, @@ -8603,10 +8971,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, @@ -8626,8 +8994,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, @@ -8644,10 +9013,10 @@ 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, @@ -8667,8 +9036,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, @@ -8683,10 +9053,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_SIS_501, .init = machine_at_p5sp4_init, - .pad = 0, - .pad0 = 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, @@ -8706,8 +9076,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, @@ -8725,10 +9096,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430NX, .init = machine_at_plato_init, - .pad = 0, - .pad0 = 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, @@ -8748,8 +9119,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 + }, + /* Same as Intel Premiere PCI/II, but with a Dell OEM BIOS */ + { + .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_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 | MACHINE_ACPI, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -8765,10 +9177,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430NX, .init = machine_at_ambradp90_init, - .pad = 0, - .pad0 = 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, @@ -8788,8 +9200,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, @@ -8804,10 +9217,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430NX, .init = machine_at_430nx_init, - .pad = 0, - .pad0 = 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, @@ -8827,8 +9240,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, @@ -8845,10 +9259,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, @@ -8868,8 +9282,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, @@ -8884,10 +9299,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, @@ -8907,8 +9322,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, @@ -8925,10 +9341,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, @@ -8946,10 +9362,11 @@ const machine_t machines[] = { .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, @@ -8964,10 +9381,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, @@ -8987,8 +9404,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, @@ -9003,10 +9421,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, @@ -9026,8 +9444,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, @@ -9046,10 +9465,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), @@ -9069,8 +9488,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, @@ -9086,10 +9506,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, @@ -9109,8 +9529,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, @@ -9127,10 +9548,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), @@ -9150,8 +9571,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, @@ -9166,10 +9588,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), @@ -9189,8 +9611,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, @@ -9205,10 +9628,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), @@ -9228,8 +9651,9 @@ 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, @@ -9247,10 +9671,10 @@ const machine_t machines[] = { .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, @@ -9270,8 +9694,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, @@ -9286,10 +9711,10 @@ const machine_t machines[] = { .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, @@ -9309,8 +9734,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, @@ -9325,10 +9751,10 @@ const machine_t machines[] = { .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, @@ -9348,8 +9774,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, @@ -9366,10 +9793,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, @@ -9387,10 +9814,11 @@ const machine_t machines[] = { .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, @@ -9406,10 +9834,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, @@ -9429,12 +9857,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 }, @@ -9447,10 +9876,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, @@ -9468,14 +9897,15 @@ const machine_t machines[] = { .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 }, @@ -9488,10 +9918,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, @@ -9509,11 +9939,12 @@ const machine_t machines[] = { .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, @@ -9529,10 +9960,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, @@ -9544,21 +9975,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 | MACHINE_ACPI, .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'. */ @@ -9568,10 +10000,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, @@ -9591,8 +10023,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, @@ -9608,10 +10041,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, @@ -9629,14 +10062,15 @@ const machine_t machines[] = { .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 }, @@ -9647,10 +10081,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, @@ -9670,8 +10104,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, @@ -9686,10 +10121,10 @@ const machine_t machines[] = { .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), @@ -9709,8 +10144,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, @@ -9729,10 +10165,10 @@ const machine_t machines[] = { .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, @@ -9752,8 +10188,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, @@ -9768,10 +10205,10 @@ const machine_t machines[] = { .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, @@ -9791,8 +10228,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, @@ -9807,10 +10245,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, @@ -9830,8 +10268,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, @@ -9847,10 +10286,10 @@ const machine_t machines[] = { .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, @@ -9868,10 +10307,11 @@ const machine_t machines[] = { .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, @@ -9881,17 +10321,19 @@ const machine_t machines[] = { }, /* 430VX */ - /* Has AMIKey H KBC firmware (AMIKey-2). */ + /* 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] ECS P5VX-B", - .internal_name = "p5vxb", + .name = "[i430VX] Dell Hannibal+", + .internal_name = "dell_430vx", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_p5vxb_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_dell_430vx_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, @@ -9911,8 +10353,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 AMIKey H KBC firmware (AMIKey-2). */ + { + .name = "[i430VX] ECS P5VX-B", + .internal_name = "p5vxb", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_p5vxb_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_ACPI, + .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, @@ -9929,10 +10412,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, @@ -9952,8 +10435,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, @@ -9970,10 +10454,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, @@ -9993,8 +10477,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, @@ -10009,10 +10494,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, @@ -10032,8 +10517,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, @@ -10051,10 +10537,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), @@ -10074,8 +10560,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, @@ -10090,10 +10577,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, @@ -10113,8 +10600,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, @@ -10129,10 +10617,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, @@ -10152,8 +10640,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, @@ -10170,10 +10659,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, @@ -10193,27 +10682,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, @@ -10233,28 +10722,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 }, - /* 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] Toshiba Equium 5200D", - .internal_name = "equium5200", + .name = "[i430HX] Intel CU430HX", + .internal_name = "cu430hx", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_equium5200_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .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, @@ -10266,21 +10754,62 @@ 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_ACPI, .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 + }, + /* 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, + .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_ACPI, + .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 }, /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the @@ -10293,10 +10822,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, @@ -10314,10 +10843,11 @@ const machine_t machines[] = { .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, @@ -10332,10 +10862,10 @@ const machine_t machines[] = { .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, @@ -10355,8 +10885,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, @@ -10373,10 +10904,10 @@ const machine_t machines[] = { .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, @@ -10396,8 +10927,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, @@ -10412,10 +10944,10 @@ const machine_t machines[] = { .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, @@ -10435,8 +10967,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, @@ -10452,10 +10985,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, @@ -10475,8 +11008,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, @@ -10491,10 +11025,10 @@ const machine_t machines[] = { .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, @@ -10514,8 +11048,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, @@ -10531,10 +11066,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, @@ -10554,12 +11089,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 }, @@ -10570,10 +11106,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, @@ -10593,12 +11129,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 }, @@ -10609,10 +11146,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, @@ -10632,8 +11169,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, @@ -10648,10 +11186,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, @@ -10671,8 +11209,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, @@ -10689,10 +11228,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, @@ -10704,20 +11243,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_ACPI, .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 }, @@ -10728,10 +11268,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, @@ -10751,8 +11291,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, @@ -10768,10 +11309,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, @@ -10791,8 +11332,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, @@ -10808,10 +11350,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, @@ -10831,8 +11373,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, @@ -10849,10 +11392,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, @@ -10872,8 +11415,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, @@ -10888,10 +11432,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, @@ -10911,8 +11455,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, @@ -10928,10 +11473,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, @@ -10951,8 +11496,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, @@ -10968,10 +11514,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, @@ -10991,8 +11537,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 + }, + /* 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, + .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, @@ -11007,10 +11594,10 @@ const machine_t machines[] = { .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, @@ -11030,8 +11617,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, @@ -11046,10 +11634,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, @@ -11069,8 +11657,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, @@ -11085,10 +11674,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, @@ -11108,8 +11697,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, @@ -11127,10 +11717,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, @@ -11150,8 +11740,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, @@ -11169,10 +11760,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, @@ -11192,8 +11783,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, @@ -11205,54 +11797,15 @@ 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 = "cb52x_si", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_SIS_5571, - .init = machine_at_r534f_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, - .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_ACPI, - .ram = { - .min = 8192, - .max = 393216, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .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] MSI MS-5146", - .internal_name = "ms5146", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_SIS_5571, - .init = machine_at_ms5146_init, - .pad = 0, - .pad0 = 0, - .pad1 = MACHINE_AVAILABLE, - .pad2 = 0, + .init = machine_at_cb52x_si_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, @@ -11270,10 +11823,91 @@ const machine_t machines[] = { .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, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the SiS 5571 chipset with on-chip KBC. */ + { + .name = "[SiS 5571] MSI MS-5146", + .internal_name = "ms5146", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5571, + .init = machine_at_ms5146_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 = 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, + .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 + }, + /* 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_ACPI, + .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, @@ -11284,55 +11918,16 @@ const machine_t machines[] = { /* ALi ALADDiN IV+ */ /* Has the ALi M1543 southbridge with on-chip KBC. */ - { - .name = "[ALi ALADDiN IV+] PC Chips M560", - .internal_name = "m560", - .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, - .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 | MACHINE_ACPI, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0, - .gpio = 0, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the ALi M1543 southbridge with on-chip KBC. */ { .name = "[ALi ALADDiN IV+] MSI MS-5164", .internal_name = "ms5164", .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, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, @@ -11352,8 +11947,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 the ALi M1543 southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN IV+] PC Chips M560", + .internal_name = "m560", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, + .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 = 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 | MACHINE_ACPI, + .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, @@ -11371,10 +12007,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, @@ -11394,8 +12030,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, @@ -11411,10 +12048,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, @@ -11434,8 +12071,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, @@ -11450,10 +12088,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, @@ -11473,8 +12111,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, @@ -11489,10 +12128,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, @@ -11512,8 +12151,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, @@ -11531,10 +12171,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, @@ -11554,8 +12194,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, @@ -11571,10 +12212,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, @@ -11594,8 +12235,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, @@ -11611,10 +12253,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, @@ -11634,8 +12276,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, @@ -11651,10 +12294,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, @@ -11674,8 +12317,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, @@ -11693,10 +12337,10 @@ const machine_t machines[] = { .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, @@ -11716,8 +12360,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, @@ -11734,10 +12379,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, @@ -11757,8 +12402,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, @@ -11773,10 +12419,10 @@ const machine_t machines[] = { .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, @@ -11796,8 +12442,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, @@ -11813,10 +12460,10 @@ const machine_t machines[] = { .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, @@ -11836,8 +12483,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, @@ -11845,16 +12493,57 @@ const machine_t machines[] = { .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_ACPI, + .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 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, @@ -11874,8 +12563,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, @@ -11892,10 +12582,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, @@ -11915,8 +12605,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, @@ -11933,10 +12624,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, @@ -11956,8 +12647,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 = "lgibm440fx", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_lgibm440fx_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_ACPI, + .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, @@ -11972,10 +12704,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, @@ -11995,8 +12727,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, @@ -12013,10 +12746,10 @@ const machine_t machines[] = { .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, @@ -12036,8 +12769,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, @@ -12055,10 +12789,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, @@ -12078,8 +12812,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, @@ -12096,10 +12831,10 @@ const machine_t machines[] = { .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, @@ -12119,8 +12854,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, @@ -12136,10 +12872,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, @@ -12159,8 +12895,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, @@ -12178,10 +12915,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, @@ -12201,8 +12938,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, @@ -12218,10 +12956,10 @@ const machine_t machines[] = { .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440LX, .init = machine_at_spitfire_init, - .pad = 0, - .pad0 = 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, @@ -12241,8 +12979,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 SM(S)C FDC37M60x Super I/O chip with on-chip KBC with Phoenix or + AMIKey-2 KBC firmware. */ + { + .name = "[i440LX] NEC Mate NX MA30D/23D", + .internal_name = "mate_nx_ma30d_23d", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440LX, + .init = machine_at_mate_nx_ma30d_23d_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, + .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, @@ -12260,10 +13040,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, @@ -12283,8 +13063,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, @@ -12302,10 +13083,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, @@ -12325,8 +13106,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, @@ -12342,10 +13124,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, @@ -12365,8 +13147,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, @@ -12382,10 +13165,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, @@ -12405,8 +13188,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, @@ -12422,10 +13206,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, @@ -12445,8 +13229,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, @@ -12462,10 +13247,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, @@ -12485,8 +13270,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, @@ -12502,10 +13288,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, @@ -12525,8 +13311,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 the AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)", + .internal_name = "lgibm440bx", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_lgibm440bx_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 = 50000000, + .max_bus = 112121212, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .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, @@ -12542,10 +13369,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, @@ -12565,13 +13392,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 @@ -12582,10 +13410,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, @@ -12605,8 +13433,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, @@ -12624,10 +13453,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, @@ -12647,12 +13476,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 }, @@ -12664,10 +13494,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, @@ -12687,12 +13517,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 }, @@ -12706,10 +13537,10 @@ const machine_t machines[] = { .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, @@ -12729,8 +13560,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, @@ -12748,10 +13580,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, @@ -12771,8 +13603,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, @@ -12788,10 +13621,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, @@ -12811,8 +13644,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, @@ -12828,10 +13662,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, @@ -12851,8 +13685,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, @@ -12868,10 +13703,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, @@ -12891,13 +13726,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 }, @@ -12911,10 +13747,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, @@ -12934,8 +13770,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, @@ -12954,10 +13791,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, @@ -12977,13 +13814,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 */ @@ -12995,10 +13833,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, @@ -13018,13 +13856,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 }, @@ -13038,10 +13877,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, @@ -13061,8 +13900,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, @@ -13078,10 +13918,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, @@ -13101,8 +13941,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, @@ -13121,10 +13962,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, @@ -13144,8 +13985,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, @@ -13163,10 +14005,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, @@ -13186,8 +14028,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, @@ -13203,10 +14046,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, @@ -13226,8 +14069,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, @@ -13243,10 +14087,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, @@ -13266,8 +14110,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, @@ -13285,10 +14130,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, @@ -13308,8 +14153,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, @@ -13327,10 +14173,10 @@ const machine_t machines[] = { .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, @@ -13350,8 +14196,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, @@ -13359,6 +14206,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, + .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 @@ -13369,10 +14257,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, @@ -13392,8 +14280,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, @@ -13409,10 +14298,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, @@ -13432,8 +14321,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, @@ -13449,10 +14339,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, @@ -13472,8 +14362,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, @@ -13489,10 +14380,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, @@ -13512,13 +14403,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 }, @@ -13531,10 +14423,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), @@ -13554,8 +14446,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, @@ -13570,10 +14463,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, @@ -13593,8 +14486,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, @@ -13607,9 +14501,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) { @@ -13617,9 +14525,50 @@ machine_get_p1(void) } void -machine_load_p1(UNUSED(int m)) +machine_set_p1_default(uint8_t val) { - machine_p1 = machines[machine].kbc_p1; + 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) +{ + return machine_gpio_default; } uint32_t @@ -13629,15 +14578,97 @@ machine_get_gpio(void) } void -machine_load_gpio(UNUSED(int m)) +machine_set_gpio_default(uint32_t val) { - machine_gpio = machines[machine].gpio; + machine_gpio = machine_gpio_default = val; } void -machine_set_gpio(uint32_t gpio) +machine_set_gpio(uint32_t val) { - machine_gpio = gpio; + 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) +{ + 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_init_gpio_acpi(void) +{ + machine_gpio_acpi = machine_gpio_acpi_default = machines[machine].gpio_acpi; } int @@ -13646,16 +14677,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 * @@ -13721,16 +14752,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 @@ -13786,12 +14817,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 001e7b5bc..d3d5d1ce7 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 - row.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/i2c_eeprom.c b/src/mem/i2c_eeprom.c index 7d83bbe88..8e4a6cc14 100644 --- a/src/mem/i2c_eeprom.c +++ b/src/mem/i2c_eeprom.c @@ -60,7 +60,7 @@ 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; @@ -77,8 +77,7 @@ i2c_eeprom_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *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; } @@ -100,8 +99,7 @@ i2c_eeprom_write(UNUSED(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; } @@ -137,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); @@ -149,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; } @@ -161,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/mem.c b/src/mem/mem.c index 3facfcc31..0b002b302 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> @@ -119,14 +120,15 @@ 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]; @@ -2694,7 +2696,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"); @@ -2702,17 +2705,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]); } diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c new file mode 100644 index 000000000..21c62b833 --- /dev/null +++ b/src/mem/mmu_2386.c @@ -0,0 +1,990 @@ +/* + * 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> + +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); + + 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; + + 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; + 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(addr, addr64a[0]) | (((uint16_t) readmembl_no_mmut(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; + 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(addr, addr64a[0], val); + writemembl_no_mmut(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(addr, a64[0]) | (((uint16_t) readmembl_no_mmut(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(addr, a64[0], val); + writemembl_no_mmut(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); + GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); + + mem_logical_addr = addr; + + high_page = 0; + + if (addr & 3) { + if (!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(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); + GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); + + mem_logical_addr = addr; + + high_page = 0; + + if (addr & 3) { + if (!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(addr, &(addr64a[0]), val); + writememwl_no_mmut(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 (addr & 3) { + if (!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(addr, a64) | ((uint32_t) (readmemwl_no_mmut(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 (addr & 3) { + if (!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(addr, &(a64[0]), val); + writememwl_no_mmut(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); + 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(addr, addr64a) | (((uint64_t) readmemll_no_mmut(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); + 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(addr, addr64a, val); + writememll_no_mmut(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; + + for (i = 0; i < num; i++) + a64[i] = (uint64_t) addr; + + for (i = 0; i < num; i++) { + if (cr0 >> 31) { + /* 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/row.c b/src/mem/row.c index f4caf7a24..ccd0325a4 100644 --- a/src/mem/row.c +++ b/src/mem/row.c @@ -214,7 +214,7 @@ row_reset(UNUSED(void *priv)) uint32_t boundary; uint32_t shift; - for (uint8_t i = (rows_num - 1); i >= 0; i--) + for (int8_t i = (rows_num - 1); i >= 0; i--) row_disable(i); for (uint8_t i = 0; i < rows_num; i++) { diff --git a/src/mem/spd.c b/src/mem/spd.c index cbc9ac2b7..a3bcba46d 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -349,9 +349,12 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit uint8_t dimm; uint8_t drb; uint8_t apollo = 0; + uint8_t two_step = !!(drb_unit & 0x80); uint16_t size; uint16_t rows[SPD_MAX_SLOTS]; + drb_unit &= 0x7f; + /* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */ if (reg_max < reg_min) { apollo = reg_max; @@ -384,7 +387,10 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit } /* Determine the DRB register to write. */ - drb = reg_min + row; + if (two_step) + drb = reg_min + (row << 1); + else + drb = reg_min + row; if (apollo && ((drb & 0xf) < 0xa)) drb = apollo + (drb & 0xf); diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index 22b147933..472a042d1 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 Melody Goad. * Copyright 2022-2023 Jasmine Iwanek. */ #include @@ -469,7 +465,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)); @@ -497,11 +493,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. */ @@ -514,14 +510,14 @@ sst_init(const device_t *info) static void sst_close(void *priv) { - FILE *f; + 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); } } diff --git a/src/minitrace/minitrace.c b/src/minitrace/minitrace.c index 36a3a535b..290486ec5 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 ce1bba325..b0ba913d5 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -14,7 +14,8 @@ # 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) find_package(PkgConfig REQUIRED) pkg_check_modules(SLIRP REQUIRED IMPORTED_TARGET slirp) diff --git a/src/network/net_3c501.c b/src/network/net_3c501.c index b3a903c7b..5b9fc0cac 100644 --- a/src/network/net_3c501.c +++ b/src/network/net_3c501.c @@ -373,7 +373,7 @@ elnkR3HardReset(threec501_t *dev) static __inline int padr_match(threec501_t *dev, const uint8_t *buf) { - const struct ether_header *hdr = (struct ether_header *) buf; + const struct ether_header *hdr = (const struct ether_header *) buf; int result; /* Checks own + broadcast as well as own + multicast. */ @@ -389,7 +389,7 @@ static __inline int padr_bcast(threec501_t *dev, const uint8_t *buf) { static uint8_t aBCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - const struct ether_header *hdr = (struct ether_header *) buf; + 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; @@ -401,8 +401,8 @@ 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; } diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index 1e50ddd45..1c308e913 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -66,7 +66,7 @@ mcast_index(const void *dst) uint32_t crc = 0xffffffffL; int carry; uint8_t b; - const uint8_t *ep = (uint8_t *) dst; + const uint8_t *ep = (const uint8_t *) dst; for (int8_t i = 6; --i >= 0;) { b = *ep++; diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/network/net_eeprom_nmc93cxx.c new file mode 100644 index 000000000..1e2fd1645 --- /dev/null +++ b/src/network/net_eeprom_nmc93cxx.c @@ -0,0 +1,282 @@ +/* + * 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) +{ + /* 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_l80225.c b/src/network/net_l80225.c new file mode 100644 index 000000000..6493edec6 --- /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 231b7d481..c7fba404f 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -68,6 +68,7 @@ #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. */ @@ -96,36 +97,45 @@ static uint8_t rtl8019as_pnp_rom[] = { typedef struct nic_t { dp8390_t *dp8390; + const char *name; + + 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]; + int board; int is_pci; int is_mca; int is_8bit; - uint32_t base_address; int base_irq; + int has_bios; + + uint32_t base_address; uint32_t bios_addr; uint32_t bios_size; uint32_t bios_mask; - int card; /* PCI card slot */ - int has_bios; - int 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 */ - - /* RTL8019AS/RTL8029AS registers */ - uint8_t config0; - uint8_t config2; - uint8_t config3; - uint8_t _9346cr; - uint32_t pad0; - - /* POS registers, MCA boards only */ - uint8_t pos_regs[8]; } nic_t; #ifdef ENABLE_NE2K_LOG @@ -149,13 +159,13 @@ nelog(int lvl, const char *fmt, ...) static void nic_interrupt(void *priv, int set) { - const nic_t *dev = (nic_t *) priv; + nic_t *dev = (nic_t *) priv; 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); @@ -749,9 +759,7 @@ nic_pci_write(UNUSED(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 */ -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x11: /* PCI_BAR */ case 0x12: /* PCI_BAR */ @@ -804,7 +812,7 @@ static void nic_rom_init(nic_t *dev, char *s) { uint32_t temp; - FILE *f; + FILE *fp; if (s == NULL) return; @@ -812,10 +820,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; @@ -1086,8 +1094,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. */ diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 4981fb9a3..e1747580b 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -122,15 +122,15 @@ struct pcap_if { }; struct pcap_send_queue { - u_int maxlen; /* Maximum size of the queue, in bytes. This + unsigned int maxlen; /* Maximum size of the queue, in bytes. This variable contains the size of the buffer field. */ - u_int len; /* Current size of the queue, in bytes. */ + unsigned int len; /* Current size of the queue, in bytes. */ char *buffer; /* Buffer containing the packets to be sent. */ }; typedef struct pcap_send_queue pcap_send_queue; -typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes); +typedef void (*pcap_handler)(unsigned char *user, const struct pcap_pkthdr *h, const unsigned char *bytes); #endif typedef struct { @@ -169,15 +169,15 @@ static int (*f_pcap_setnonblock)(void *, int, char *); static int (*f_pcap_set_immediate_mode)(void *, int); static int (*f_pcap_set_promisc)(void *, int); static int (*f_pcap_set_snaplen)(void *, int); -static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, u_char *user); +static int (*f_pcap_dispatch)(void *, int, pcap_handler callback, unsigned char *user); static void *(*f_pcap_create)(const char *, char *); static int (*f_pcap_activate)(void *); static void *(*f_pcap_geterr)(void *); #ifdef _WIN32 static HANDLE (*f_pcap_getevent)(void *); static int (*f_pcap_sendqueue_queue)(void *, void *, void *); -static u_int (*f_pcap_sendqueue_transmit)(void *, void *, int sync); -static void *(*f_pcap_sendqueue_alloc)(u_int memsize); +static unsigned int (*f_pcap_sendqueue_transmit)(void *, void *, int sync); +static void *(*f_pcap_sendqueue_alloc)(unsigned int memsize); static void (*f_pcap_sendqueue_destroy)(void *); #else static int (*f_pcap_get_selectable_fd)(void *); @@ -294,7 +294,7 @@ net_pcap_thread(void *priv) break; case NET_EVENT_RX: - f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *) pcap); + f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (unsigned char *) pcap); break; default: @@ -341,7 +341,7 @@ net_pcap_thread(void *priv) } if (pfd[NET_EVENT_RX].revents & POLLIN) { - f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (u_char *) pcap); + f_pcap_dispatch(pcap->pcap, PCAP_PKT_BATCH, net_pcap_rx_handler, (unsigned char *) pcap); } } diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 85d2cb8bb..02e3d32e7 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -47,6 +47,7 @@ #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. */ @@ -216,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; @@ -413,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); @@ -747,7 +749,7 @@ static const uint32_t crctab[256] = static __inline int padr_match(nic_t *dev, const uint8_t *buf, UNUSED(int size)) { - const struct ether_header *hdr = (struct ether_header *) buf; + const struct ether_header *hdr = (const struct ether_header *) buf; int result; uint8_t padr[6]; @@ -773,7 +775,7 @@ static __inline int padr_bcast(nic_t *dev, const uint8_t *buf, UNUSED(size_t size)) { static uint8_t aBCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - const struct ether_header *hdr = (struct ether_header *) buf; + 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); @@ -784,7 +786,7 @@ padr_bcast(nic_t *dev, const uint8_t *buf, UNUSED(size_t size)) static int ladr_match(nic_t *dev, const uint8_t *buf, UNUSED(size_t size)) { - const 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; @@ -864,7 +866,7 @@ 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: @@ -1997,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: @@ -2995,8 +2997,7 @@ 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); + 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; @@ -3100,9 +3101,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 = "" } }, }, @@ -3115,6 +3119,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 }, @@ -3161,9 +3166,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 = "" } }, }, diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c new file mode 100644 index 000000000..74a1f90ff --- /dev/null +++ b/src/network/net_rtl8139.c @@ -0,0 +1,3298 @@ +/* + * 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/net_rtl8139.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_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) +{ + uint16_t ret = s->CSCR; + + 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; + + 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 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; + case 0x14: + 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); + rtl8139_log("New memory base: %08X\n", s->mem_base); + if (s->pci_conf[0x4] & PCI_COMMAND_MEM) + mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 256); + 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_tulip.c b/src/network/net_tulip.c new file mode 100644 index 000000000..b74b345bc --- /dev/null +++ b/src/network/net_tulip.c @@ -0,0 +1,1594 @@ +/* + * 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/net_tulip.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; + + 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->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): + /* 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; + 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): + 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]; + 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; + 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) +{ + return tulip_write(addr, data, opaque); +} + +static void +tulip_mem_writew(uint32_t addr, uint16_t data, void *opaque) +{ + return tulip_write(addr, data, opaque); +} + +static void +tulip_mem_writel(uint32_t addr, uint32_t data, void *opaque) +{ + return tulip_write(addr, data, opaque); +} + +static uint8_t +tulip_mem_readb(uint32_t addr, void *opaque) +{ + return tulip_read(addr, opaque); +} + +static uint16_t +tulip_mem_readw(uint32_t addr, void *opaque) +{ + return tulip_read(addr, opaque); +} + +static uint32_t +tulip_mem_readl(uint32_t addr, void *opaque) +{ + return tulip_read(addr, opaque); +} + +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) + 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; + case 0x14: + ret = (tulip_pci_bar[1].addr_regs[0] & 0x80); + break; + case 0x15: + ret = tulip_pci_bar[1].addr_regs[1]; + 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: + 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_set_addr(&s->memory, s->MMIOBase, 128); + 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; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + mem_mapping_disable(&s->memory); + tulip_pci_bar[1].addr_regs[addr & 3] = val; + tulip_pci_bar[1].addr &= 0xffffff80; + 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) + mem_mapping_set_addr(&s->memory, s->MMIOBase, 128); + } + 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: + 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) { + s->bios_addr = 0xD0000; + s->has_bios = device_get_config_int("bios"); + } else { + s->bios_addr = 0; + s->has_bios = 0; + } + + 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); + mem_mapping_disable(&s->memory); + + s->device_info = info; + + /*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; + + 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 = (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[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 +}; diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 44df03e6e..04b922aaf 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -64,6 +64,7 @@ #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" @@ -734,9 +735,8 @@ wd_init(const device_t *info) /* Ethernet, MCA, 5x3 interface chip, RAM 16k */ case WD8003EA: dev->board_chip = WE_ID_SOFT_CONFIG; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; + /* Ethernet, MCA, no interface chip, RAM 16k */ case WD8003ETA: dev->board_chip |= WE_TYPE_WD8013EBT | WE_ID_BUS_MCA; diff --git a/src/network/network.c b/src/network/network.c index eec85fcb0..38af502b2 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -73,6 +73,8 @@ #include <86box/net_pcnet.h> #include <86box/net_plip.h> #include <86box/net_wd8003.h> +#include <86box/net_tulip.h> +#include <86box/net_rtl8139.h> #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN @@ -94,8 +96,23 @@ 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, @@ -114,7 +131,11 @@ 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, &pcnet_am79c960_vlb_device, NULL }; @@ -564,7 +585,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 +691,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 +740,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 +753,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/nvr.c b/src/nvr.c index f403984e4..d833618d0 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -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 1ba9fd2b2..c66799579 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,6 +295,7 @@ #define FLAG_AMI_1995_HACK 0x08 #define FLAG_P6RP4_HACK 0x10 #define FLAG_PIIX4 0x20 +#define FLAG_MULTI_BANK 0x40 typedef struct local_t { int8_t stat; @@ -306,8 +306,8 @@ typedef struct local_t { uint8_t read_addr; uint8_t wp_0d; uint8_t wp_32; - uint8_t pad; - uint8_t pad0; + uint8_t irq_state; + uint8_t smi_status; uint8_t addr[8]; uint8_t wp[2]; @@ -317,6 +317,8 @@ typedef struct local_t { int16_t count; int16_t state; + int32_t smi_enable; + uint64_t ecount; uint64_t rtc_time; pc_timer_t update_timer; @@ -330,7 +332,7 @@ static void time_get(nvr_t *nvr, struct tm *tm) { const local_t *local = (local_t *) nvr->data; - int8_t temp; + int8_t temp; if (nvr->regs[RTC_REGB] & REGB_DM) { /* NVR is in Binary data mode. */ @@ -368,7 +370,7 @@ static void time_set(nvr_t *nvr, struct tm *tm) { const local_t *local = (local_t *) nvr->data; - int year = (tm->tm_year + 1900); + int year = (tm->tm_year + 1900); if (nvr->regs[RTC_REGB] & REGB_DM) { /* NVR is in Binary data mode. */ @@ -434,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) @@ -442,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; } } @@ -525,13 +541,7 @@ timer_intr(void *priv) 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); } } @@ -541,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); } } @@ -557,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)) @@ -567,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; } } @@ -583,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 */ @@ -637,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; } } } @@ -665,9 +672,12 @@ nvr_write(uint16_t addr, uint8_t val, void *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]); @@ -698,9 +708,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: @@ -978,6 +988,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) { @@ -1081,6 +1118,12 @@ nvr_at_init(const device_t *info) 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. */ @@ -1175,6 +1218,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 b13312545..67eaccc38 100644 --- a/src/nvr_ps2.c +++ b/src/nvr_ps2.c @@ -111,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)); @@ -130,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; @@ -147,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 c86006a1a..15a119cb7 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 @@ -36,53 +32,69 @@ #include <86box/keyboard.h> #include <86box/plat_unused.h> -typedef struct pci_card_t { - uint8_t bus; - uint8_t id; - uint8_t 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 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 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; -int pci_take_over_io; +int pci_burst_time; +int agp_burst_time; +int pci_nonburst_time; +int agp_nonburst_time; -uint32_t pci_base = 0xc000; -uint32_t pci_size = 0x1000; +int pci_flags; -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; +uint32_t pci_base = 0xc000; +uint32_t pci_size = 0x1000; -static void pci_reset_regs(void); +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; @@ -102,548 +114,6 @@ pci_log(const char *fmt, ...) # define pci_log(fmt, ...) #endif -static void -pci_clear_slot(int card) -{ - 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; -} - -void -pci_relocate_slot(int type, int new_slot) -{ - 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; -} - -static void -pci_cf8_write(UNUSED(uint16_t port), uint32_t val, UNUSED(void *priv)) -{ - 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; -} - -static uint32_t -pci_cf8_read(UNUSED(uint16_t port), UNUSED(void *priv)) -{ - return pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16) | (pci_enable << 31); -} - -static void -pci_write(uint16_t port, uint8_t val, UNUSED(void *priv)) -{ - 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; - - default: - break; - } -} - -static void -pci_writew(uint16_t port, uint16_t val, UNUSED(void *priv)) -{ - 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; - - default: - break; - } -} - -static void -pci_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) -{ - 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 %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); - } -#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; - - default: - break; - } -} - -static uint8_t -pci_read(uint16_t port, UNUSED(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 - break; - - default: - break; - } - - 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, UNUSED(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 - break; - - default: - break; - } - - 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, UNUSED(void *priv)) -{ - uint8_t slot = 0; - uint32_t ret = 0xffffffff; - - 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); - 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 - break; - - default: - 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; -} - -void -pci_set_pmc(uint8_t pmc) -{ - pci_log("pci_set_pmc(%02X)\n", pmc); -#if 0 - pci_reset_regs(); -#endif - - if (!pci_pmc && (pmc & 0x01)) { - pci_log("PMC: Dellocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io &= ~PCI_IO_ON; - - 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)) { - pci_log("PMC: Redellocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io &= ~PCI_IO_ON; - if (pci_key) { - pci_log("PMC: Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io |= PCI_IO_ON; - } - - 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); - } - - pci_pmc = (pmc & 0x01); -} - -static void -pci_type2_write_reg(uint16_t port, uint8_t val) -{ - uint8_t slot = 0; - - 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:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Writing to unassigned PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index); -#endif -} - -void -pci_type2_write(uint16_t port, uint8_t val, UNUSED(void *priv)) -{ - switch (port) { - case 0xcf8: - pci_func = (val >> 1) & 7; - - if (val & 0xf0) { - pci_log("CF8: Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io |= PCI_IO_ON; - } else { - pci_log("CF8: Dellocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - pci_take_over_io &= ~PCI_IO_ON; - } - - pci_key = val & 0xf0; - break; - case 0xcfa: - pci_bus = val; - - pci_log("CFA: Allocating ports %04X-%04X...\n", pci_base, pci_base + pci_size - 1); - - /* Evidently, writing here, we should also enable the - configuration space. */ - pci_take_over_io |= PCI_IO_ON; - - /* Mark as enabled. */ - pci_key |= 0x100; - break; - case 0xcfb: - pci_log("Write %02X to port 0CFB\n", val); - pci_set_pmc(val); - break; - - case 0xc000 ... 0xc0ff: - if (pci_take_over_io == 0x00000000) - break; - - pci_type2_write_reg(port, val); - break; - - case 0xc100 ... 0xcfff: - if (!(pci_take_over_io & PCI_IO_ON)) - break; - - pci_type2_write_reg(port, val); - break; - - default: - break; - } -} - -void -pci_type2_writew(uint16_t port, uint16_t val, void *priv) -{ - pci_type2_write(port, val & 0xff, priv); - pci_type2_write(port + 1, val >> 8, priv); -} - -void -pci_type2_writel(uint16_t port, uint32_t val, void *priv) -{ - pci_type2_writew(port, val & 0xffff, priv); - pci_type2_writew(port + 2, val >> 16, priv); -} - -static void -pci_type2_cfb_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_reg(uint16_t port) -{ - uint8_t slot = 0; - uint8_t ret = 0xff; - - 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:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, pci_card, slot, pci_func, pci_index); -#endif - } -#ifdef ENABLE_PCI_LOG - else - pci_log("Reading from unasisgned PCI card on slot %02X:%02X (pci_cards[%i]) (%02X:%02X)...\n", pci_bus, 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; -} - -uint8_t -pci_type2_read(uint16_t port, UNUSED(void *priv)) -{ - uint8_t ret = 0xff; - - switch (port) { - case 0xcf8: - ret = pci_key | (pci_func << 1); - break; - case 0xcfa: - ret = pci_bus; - break; - case 0xcfb: - ret = pci_pmc; - break; - - case 0xc000 ... 0xc0ff: - if (pci_take_over_io == 0x00000000) - break; - - ret = pci_type2_read_reg(port); - break; - - case 0xc100 ... 0xcfff: - if (!(pci_take_over_io & PCI_IO_ON)) - break; - - ret = pci_type2_read_reg(port); - break; - - default: - break; - } - - return ret; -} - -uint16_t -pci_type2_readw(uint16_t port, void *priv) -{ - uint16_t ret = pci_type2_read(port, priv); - ret |= ((uint16_t) pci_type2_read(port + 1, priv)) << 8; - - return ret; -} - -uint32_t -pci_type2_readl(uint16_t port, void *priv) -{ - uint32_t ret = pci_type2_readw(port, priv); - ret |= ((uint32_t) pci_type2_readw(port + 2, priv)) << 16; - - return ret; -} - void pci_set_irq_routing(int pci_int, int irq) { @@ -663,255 +133,96 @@ pci_enable_mirq(int mirq) } void -pci_set_mirq_routing(int mirq, int irq) +pci_set_mirq_routing(int mirq, uint8_t irq) { pci_mirqs[mirq].irq_line = irq; } -void -pci_set_mirq(uint8_t mirq, int level) +uint8_t +pci_get_mirq_level(int mirq) { - uint8_t irq_line = 0; - uint8_t irq_bit; - - 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 (pci_mirqs[mirq].irq_line > 0x0f) { - pci_log("pci_set_mirq(%02X): IRQ line is disabled\n", mirq); - return; - } - - 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); - 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); - } - - /* 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); - } - - pci_log("pci_set_mirq(%02X): Edge-triggered interrupt, not marking\n", mirq); + return pci_mirqs[mirq].irq_level; } void -pci_set_irq(uint8_t card, uint8_t pci_int) +pci_set_mirq_level(int mirq, uint8_t level) +{ + pci_mirqs[mirq].irq_level = level; +} + +/* PCI raise IRQ: the first parameter is slot if < PCI_MIRQ_BASE, MIRQ if >= PCI_MIRQ_BASE + and < PCI_DIRQ_BASE, and direct IRQ line if >= PCI_DIRQ_BASE (RichardG's + hack that may no longer be needed). */ +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 level = 0; + uint8_t is_vfio = 0; - if (!last_pci_card) { - pci_log("pci_set_irq(%02X, %02X): No PCI slots (how are we even here?!)\n", card, pci_int); + /* The fast path out an invalid PCI card. */ + if (slot == PCI_CARD_INVALID) 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); - - 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); - } -} - -void -pci_clear_mirq(uint8_t mirq, int level) -{ - uint8_t irq_line = 0; - uint8_t irq_bit; - - if (mirq >= 0xf0) { - irq_line = mirq & 0x0f; - irq_bit = 0x1D; - } else { - if (mirq > 1) { - pci_log("pci_clear_mirq(%02X): Invalid MIRQ\n", mirq); + switch (slot) { + default: return; - } - if (!pci_mirqs[mirq].enabled) { - pci_log("pci_clear_mirq(%02X): MIRQ0 disabled\n", mirq); - return; - } + case 0x00 ... PCI_CARD_MAX: + /* PCI card. */ + if (!last_pci_card) + return; - if (pci_mirqs[mirq].irq_line > 0x0f) { - pci_log("pci_clear_mirq(%02X): IRQ line is disabled\n", mirq); - return; - } + 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]; - irq_line = pci_mirqs[mirq].irq_line; - irq_bit = (0x1E + mirq); + 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; + } + } + break; + case (PCI_MIRQ_BASE | 0x00) ... (PCI_MIRQ_BASE | PCI_MIRQ_MAX): + /* MIRQ */ + slot &= PCI_MIRQ_MAX; + + if (!pci_mirqs[slot].enabled) + return; + + 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("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); + if (irq_line > PCI_IRQ_MAX) 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); - } -} - -void -pci_clear_irq(uint8_t card, uint8_t pci_int) -{ - 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_clear_irq(%02X, %02X): Using IRQ %i\n", card, pci_int, irq_line); - - 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; - } - - 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); - - 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); - } + picint_common(1 << irq_line, level, set, irq_state); } uint8_t @@ -920,12 +231,125 @@ pci_get_int(uint8_t slot, uint8_t pci_int) return pci_cards[slot].irq_routing[pci_int - PCI_INTA]; } +static void +pci_clear_slot(int card) +{ + pci_card_to_slot_mapping[pci_cards[card].bus][pci_cards[card].id] = PCI_CARD_INVALID; + + 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; +} + +/* Relocate a PCI device to a new slot, required for the configurable + IDSEL's of ALi M1543(c). */ +void +pci_relocate_slot(int type, int new_slot) +{ + int card = -1; + int old_slot; + + if ((new_slot < 0) || (new_slot > 31)) + 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; + } + } + + if (card == -1) + return; + + old_slot = pci_cards[card].id; + pci_cards[card].id = new_slot; + + if (pci_card_to_slot_mapping[0][old_slot] == card) + pci_card_to_slot_mapping[0][old_slot] = PCI_CARD_INVALID; + + 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_key_write(uint8_t val) +{ + pci_key = val & 0xf0; + + if (pci_key) + pci_flags |= FLAG_CONFIG_IO_ON; + else + pci_flags &= ~FLAG_CONFIG_IO_ON; +} + +static void +pci_io_handlers(int set) +{ + io_handler(set, 0x0cf8, 4, pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); + + 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_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_set_pmc(uint8_t pmc) +{ + pci_log("pci_set_pmc(%02X)\n", pmc); + + pci_io_handlers(0); + + pci_flags &= ~FLAG_MECHANISM_MASK; + pci_flags |= (FLAG_MECHANISM_1 + !(pmc & 0x01)); + + pci_io_handlers(1); + + pci_pmc = (pmc & 0x01); +} + +static void +pci_reg_write(uint16_t port, uint8_t val) +{ + 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; - pci_take_over_io &= ~PCI_IO_ON; + pci_flags &= ~(FLAG_CONFIG_IO_ON | FLAG_CONFIG_M1_IO_ON); } void @@ -940,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; @@ -954,68 +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(UNUSED(uint16_t port), UNUSED(void *priv)) -{ - return 0xffffffff; -} - -uint16_t -trc_readw(UNUSED(uint16_t port), UNUSED(void *priv)) -{ - return 0xffff; -} - -uint8_t -trc_read(UNUSED(uint16_t port), UNUSED(void *priv)) -{ - return trc_reg & 0xfb; -} - -static void -trc_reset(uint8_t val) +pci_trc_reset(uint8_t val) { if (val & 2) { dma_reset(); @@ -1037,110 +409,262 @@ trc_reset(uint8_t val) } void -trc_writel(UNUSED(uint16_t port), UNUSED(uint32_t val), UNUSED(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(UNUSED(uint16_t port), UNUSED(uint16_t val), UNUSED(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(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) +pci_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) { - pci_log("TRC Write: %02X\n", val); + 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); - if (!(trc_reg & 4) && (val & 4)) - trc_reset(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); - trc_reg = val & 0xfd; + 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; - if (val & 2) - trc_reg &= 0xfb; + 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; - io_sethandler(0x0cf9, 0x0001, - trc_read, trc_readw, trc_readl, trc_write, trc_writew, trc_writel, NULL); -} - -void -pci_init(int type) -{ - int c; - - pci_base = 0xc000; - pci_size = 0x1000; - - pci_slots_clear(); - - pci_reset_hard(); - - trc_init(); - - pci_type = type; - pci_switch = !!(type & PCI_CAN_SWITCH_TYPE); - - if (pci_switch) { - pci_log("PCI: Switchable configuration mechanism\n"); - pci_pmc = 0x00; - - io_sethandler(0x0cfb, 1, - pci_type2_read, NULL, NULL, pci_type2_write, NULL, pci_type2_cfb_writel, NULL); + if (port >= 0xc000) { + pci_card = (port >> 8) & 0xf; + pci_index = port & 0xfc; } - 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); + 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); + + return ret; +} + +uint8_t +pci_read(uint16_t port, UNUSED(void *priv)) +{ + uint8_t ret = 0xff; + + 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; + + 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; + + 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; + + case 0xc100 ... 0xcfff: + if ((pci_flags & FLAG_MECHANISM_2) && (pci_flags & FLAG_CONFIG_IO_ON)) + ret = pci_reg_read(port); + break; + + default: + break; } - pci_take_over_io = 0x00000000; + pci_log("PCI: [RB] Mechanism #%i port %04X = %02X\n", ((port >= 0xcfc) && (port <= 0xcff)) ? 1 : 2, port, ret); - 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; + return ret; +} + +uint16_t +pci_readw(uint16_t port, UNUSED(void *priv)) +{ + uint16_t ret = 0xffff; + + 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; + /* 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; - if (type & PCI_ALWAYS_EXPOSE_DEV0) { - pci_log("PCI: Always expose device 0\n"); - pci_base = 0xc100; - pci_size = 0x0f00; - - pci_take_over_io |= PCI_IO_DEV0; + 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; +} + +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; + } } - for (c = 0; c < 3; c++) { - pci_mirqs[c].enabled = 0; - pci_mirqs[c].irq_line = PCI_IRQ_DISABLED; - } - - pic_set_pci_flag(1); + return ret; } uint8_t @@ -1155,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) { @@ -1187,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) { const pci_card_t *dev; - uint8_t ret = 0xff; + /* 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; - for (uint8_t i = 0; i < last_pci_card; i++) { + /* 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_t *dev; - uint8_t i; - uint8_t j; + pci_card_desc_t *dev; - if (add_type < PCI_ADD_AGP) - pci_log("pci_add_card(): Adding PCI CARD at specific slot %02X [SPECIFIC]\n", add_type); + pci_log("pci_add_card(): PCI card #%02i: type = %i\n", next_pci_card, add_type); - 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; - } - - /* First, find the next available slot. */ - i = pci_find_slot(add_type, 0xff); - - if (i != 0xff) { - dev = &pci_cards[i]; - j = pci_find_slot(add_type, i); - - 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 (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; - 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; + 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_desc_t *dev; + pci_card_t *card; + uint8_t i; + 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); + + *(dev->slot) = i; + + ret = i; + } + } + + pci_clear_card(pci_card); } - return 0xff; + return ret; +} + +/* 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 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); + } + } + + 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; + } + + pic_set_pci_flag(1); } diff --git a/src/pci_dummy.c b/src/pci_dummy.c index 2046251ac..704f85d8c 100644 --- a/src/pci_dummy.c +++ b/src/pci_dummy.c @@ -9,6 +9,7 @@ #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 pci_dummy_t { @@ -16,17 +17,24 @@ typedef struct pci_dummy_t { bar_t pci_bar[2]; - uint8_t card; + 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 @@ -159,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 */ @@ -210,9 +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 */ -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x11: /* PCI_BAR */ /* Remove old I/O. */ @@ -235,7 +241,7 @@ 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; @@ -272,7 +278,7 @@ 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 6173291b4..82905261a 100644 --- a/src/pic.c +++ b/src/pic.c @@ -54,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; @@ -223,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 (!(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); - 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 @@ -326,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; } @@ -403,7 +396,7 @@ 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); @@ -415,6 +408,48 @@ pic_latch_read(UNUSED(uint16_t addr), UNUSED(void *priv)) return ret; } +uint8_t +pic_read_icw(uint8_t pic_id, uint8_t icw) +{ + pic_t *dev = pic_id ? &pic2 : &pic; + uint8_t ret = 0xff; + + switch (icw) { + case 0x00: + ret = dev->icw1; + break; + case 0x01: + ret = dev->icw2; + break; + case 0x02: + ret = dev->icw3; + break; + case 0x03: + ret = dev->icw4; + break; + } + + return ret; +} + +uint8_t +pic_read_ocw(uint8_t pic_id, uint8_t ocw) +{ + pic_t *dev = pic_id ? &pic2 : &pic; + uint8_t ret = 0xff; + + switch (ocw) { + case 0x00: + ret = dev->ocw2; + break; + case 0x01: + ret = dev->ocw3; + break; + } + + return ret; +} + uint8_t pic_read(uint16_t addr, void *priv) { @@ -494,7 +529,10 @@ 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: @@ -511,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; @@ -621,11 +663,15 @@ 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. */ @@ -645,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; + + b = i & 7; + w = 1 << i; + + if (num & w) { + if ((!!*irq_state) != !!set) + set ? dev->lines[b]++ : dev->lines[b]--; + + if (!pic_level_triggered(dev, b) || + (((!!*irq_state) != !!set) && (dev->lines[b] == (!!set)))) + lines |= w; + } } - if (num & 0xff00) { - if (level) - pic2.lines |= (num >> 8); + if ((!!*irq_state) != !!set) + *irq_state = set; - /* Latch IRQ 12 if the mouse latch is enabled. */ - if ((num & 0x1000) && mouse_latch) - latched_irqs |= 0x1000; + num = lines; + } - pic2.irr |= (num >> 8); + if (!slaves) + num &= 0x00ff; + + if (num & 0x0100) + acpi_rtc_status = !!set; + + if (num) { + if (set) { + if (smi_irq_mask & num) { + smi_raise(); + smi_irq_status |= num; + } + + if (num & 0xff00) { + /* Latch IRQ 12 if the mouse latch is enabled. */ + if ((num & 0x1000) && mouse_latch) + latched_irqs |= 0x1000; + + pic2.irr |= (num >> 8); + } + + if (num & 0x00ff) { + /* Latch IRQ 1 if the keyboard latch is enabled. */ + if (kbd_latch && (num & 0x0002)) + latched_irqs |= 0x0002; + + pic.irr |= (num & 0x00ff); + } + } else { + smi_irq_status &= ~num; + + if (num & 0xff00) { + /* Unlatch IRQ 12 if the mouse latch is enabled. */ + if ((num & 0x1000) && mouse_latch) + latched_irqs &= 0xefff; + + pic2.irr &= ~(num >> 8); + } + + if (num & 0x00ff) { + /* Unlatch IRQ 1 if the keyboard latch is enabled. */ + if (kbd_latch && (num & 0x0002)) + latched_irqs &= 0xfffd; + + pic.irr &= ~(num & 0x00ff); + } } - if (num & 0x00ff) { - if (level) - pic.lines |= (num & 0x00ff); - - /* Latch IRQ 1 if the keyboard latch is enabled. */ - if (kbd_latch && (num & 0x0002)) - latched_irqs |= 0x0002; - - pic.irr |= (num & 0x00ff); - } - } else { - smi_irq_status &= ~num; - - if (num & 0xff00) { - pic2.lines &= ~(num >> 8); - - /* Unlatch IRQ 12 if the mouse latch is enabled. */ - if ((num & 0x1000) && mouse_latch) - latched_irqs &= 0xefff; - - pic2.irr &= ~(num >> 8); - } - - if (num & 0x00ff) { - pic.lines &= ~(num & 0x00ff); - - /* Unlatch IRQ 1 if the keyboard latch is enabled. */ - if (kbd_latch && (num & 0x0002)) - latched_irqs &= 0xfffd; - - pic.irr &= ~(num & 0x00ff); - } - } - - if (!(pic.interrupt & 0x20) && !(pic2.interrupt & 0x20)) update_pending(); -} - -void -picint(uint16_t num) -{ - picint_common(num, 0, 1); -} - -void -picintlevel(uint16_t num) -{ - picint_common(num, 1, 1); -} - -void -picintc(uint16_t num) -{ - picint_common(num, 0, 0); + } } static uint8_t @@ -817,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 648e0018b..6045fd842 100644 --- a/src/pit.c +++ b/src/pit.c @@ -637,6 +637,42 @@ pit_write(uint16_t addr, uint8_t val, void *priv) extern uint8_t *ram; +uint8_t +pit_read_reg(void *priv, uint8_t reg) +{ + pit_t *dev = (pit_t *) priv; + uint8_t ret = 0xff; + + switch (reg) { + case 0x00: + case 0x02: + case 0x04: + ret = dev->counters[reg >> 1].l & 0xff; + break; + case 0x01: + case 0x03: + case 0x05: + ret = (dev->counters[reg >> 1].l >> 8) & 0xff; + break; + case 0x06: + ret = dev->ctrl; + break; + case 0x07: + /* The SiS 551x datasheet is unclear about how exactly + this register is structured. + 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) { @@ -852,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, @@ -866,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, @@ -1000,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) @@ -1014,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 { @@ -1064,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); @@ -1074,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)); @@ -1084,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); @@ -1114,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 80e359eee..f9d055375 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -404,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; @@ -498,6 +500,42 @@ pitf_write(uint16_t addr, uint8_t val, void *priv) } } +uint8_t +pitf_read_reg(void *priv, uint8_t reg) +{ + pitf_t *dev = (pitf_t *) priv; + uint8_t ret = 0xff; + + switch (reg) { + case 0x00: + case 0x02: + case 0x04: + ret = dev->counters[reg >> 1].l & 0xff; + break; + case 0x01: + case 0x03: + case 0x05: + ret = (dev->counters[reg >> 1].l >> 8) & 0xff; + break; + case 0x06: + ret = dev->ctrl; + break; + case 0x07: + /* The SiS 551x datasheet is unclear about how exactly + this register is structured. + 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) { @@ -506,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. */ @@ -654,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, @@ -668,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, @@ -731,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 340d6df2b..971b92d28 100644 --- a/src/port_6x.c +++ b/src/port_6x.c @@ -37,6 +37,7 @@ #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) @@ -45,6 +46,8 @@ #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) { @@ -52,6 +55,8 @@ port_6x_write(uint16_t port, uint8_t val, void *priv) port &= 3; + cycles -= cycles_sub; + if ((port == 3) && (dev->flags & PORT_6X_MIRROR)) port = 1; @@ -80,6 +85,8 @@ port_61_read_simple(UNUSED(uint16_t port), UNUSED(void *priv)) { uint8_t ret = ppi.pb & 0x1f; + cycles -= cycles_sub; + if (ppispeakon) ret |= 0x20; @@ -92,6 +99,8 @@ port_61_read(UNUSED(uint16_t port), void *priv) 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; @@ -190,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/printer/prt_escp.c b/src/printer/prt_escp.c index 012e8b686..8247ecfab 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -437,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; @@ -508,9 +509,12 @@ update_font(escp_t *dev) if (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; @@ -531,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. */ @@ -592,7 +596,7 @@ update_font(escp_t *dev) (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); @@ -1462,9 +1466,7 @@ process_char(escp_t *dev, uint8_t ch) dev->curr_x = dev->left_margin; if (!dev->autofeed) return 1; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x0a: /* Line feed */ if (dev->font_style & STYLE_DOUBLEWIDTHONELINE) { @@ -1580,8 +1582,8 @@ handle_char(escp_t *dev, uint8_t ch) 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; diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index d2a6797cd..ddf9faf53 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -283,9 +283,7 @@ process_char(prnt_t *dev, uint8_t ch) dev->curr_x = 0; if (!dev->autofeed) return 1; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x0a: /* Line feed */ dev->curr_x = 0; diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 7ef93b4c0..fb96de1ea 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -371,6 +371,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/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp index 4b487e65d..b5f68a286 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 7681771c6..0b0b8b26f 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 000000000..371781b7a --- /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 "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 "Unable to initialize SDL, SDL2.dll is required" +msgstr "No has estat possible inicialitzar SDL, és necessari SDL2.dll" + +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 7c82b6f4d..d86f5b635 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" @@ -656,7 +659,7 @@ msgid "(empty)" msgstr "(prázdné)" msgid "All files" -msgstr "All files" +msgstr "Všechny soubory" msgid "Turbo" msgstr "Turbo" @@ -853,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ý" @@ -932,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" @@ -1196,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 0caf925b5..9c985d871 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" @@ -853,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" @@ -1196,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 6a33f9bed..4a6a58db6 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" @@ -853,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" @@ -1201,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 5e3afdc27..ce7ceb149 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" @@ -853,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" @@ -1201,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 f864dce0d..d8d648691 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" @@ -650,13 +653,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,13 +719,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" +msgstr "Pulse F8+F12 o el botón central para liberar el ratón" msgid "Bus" msgstr "Bus" @@ -743,7 +746,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" @@ -788,10 +791,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" @@ -803,22 +806,22 @@ 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" +msgstr "Imágenes de fluxo" msgid "Unable to initialize SDL, SDL2.dll is required" msgstr "Incapaz de inicializar SDL, se requiere SDL2.dll" 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" @@ -839,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" @@ -853,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" @@ -890,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" @@ -911,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" @@ -932,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)" @@ -965,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..." @@ -1070,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" @@ -1196,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 97ecf79d5..217827f74 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" @@ -853,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" @@ -1196,8 +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 1fbff4001..be66e5924 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" @@ -853,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" @@ -932,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)" @@ -1196,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 43f01d5de..b2aa40d28 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" @@ -853,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" @@ -1196,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 bf4796ebb..352a64749 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" @@ -853,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ő" @@ -938,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)" @@ -1196,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 6c6d5f65f..df71d148b 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" @@ -853,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" @@ -866,7 +869,7 @@ 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" @@ -932,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)" @@ -1196,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 b35fa429e..7ea47bc1a 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 "マシンタイプ:" @@ -353,7 +356,7 @@ msgid "FPU:" msgstr "FPU:" msgid "Wait states:" -msgstr "待機状態:" +msgstr "ウェイトステート:" msgid "MB" msgstr "MB" @@ -365,16 +368,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 "ビデオカード:" @@ -407,16 +410,16 @@ msgid "Joystick 4..." msgstr "ジョイスティック4..." msgid "Sound card 1:" -msgstr "サウンドカード 1:" +msgstr "サウンドカード1:" msgid "Sound card 2:" -msgstr "サウンドカード 2:" +msgstr "サウンドカード2:" msgid "Sound card 3:" -msgstr "サウンドカード 3:" +msgstr "サウンドカード3:" msgid "Sound card 4:" -msgstr "サウンドカード 4:" +msgstr "サウンドカード4:" msgid "MIDI Out Device:" msgstr "MIDI出力デバイス:" @@ -434,13 +437,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 +500,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 +530,7 @@ msgid "Cassette" msgstr "カセット" msgid "Hard disks:" -msgstr "ハードディスク:" +msgstr "ハード ディスク:" msgid "&New..." msgstr "新規(&N)..." @@ -536,7 +539,7 @@ msgid "&Existing..." msgstr "既定(&E)..." msgid "&Remove" -msgstr "除去(&R)" +msgstr "削除(&R)" msgid "Bus:" msgstr "バス:" @@ -578,13 +581,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 +602,7 @@ msgid "ISA RTC:" msgstr "ISA RTCカード:" msgid "ISA Memory Expansion" -msgstr "ISAメモリー拡張カード" +msgstr "ISAメモリ拡張カード" msgid "Card 1:" msgstr "カード1:" @@ -638,7 +641,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 +653,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 +674,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 +701,7 @@ msgid "Network" msgstr "ネットワーク" msgid "Ports (COM & LPT)" -msgstr "ポート (COM & LPT)" +msgstr "ポート (COM/LPT)" msgid "Storage controllers" msgstr "ストレージコントローラ" @@ -707,22 +710,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キーまたは中ボタンでマウスを解放します" +msgstr "F8+F12キーまたは中クリックでマウスを解放します" msgid "Bus" msgstr "バス" @@ -749,7 +752,7 @@ msgid "Default" msgstr "既定値" msgid "%i Wait state(s)" -msgstr "%iつの待機状態" +msgstr "%iつのウェイト ステート" msgid "Type" msgstr "タイプ" @@ -761,7 +764,7 @@ msgid "No PCap devices found" msgstr "PCapデバイスがありません" msgid "Invalid PCap device" -msgstr "不正なPCapデバイスです" +msgstr "不正なPCapデバイス" msgid "Standard 2-button joystick(s)" msgstr "標準ジョイスティック(2ボタン)" @@ -779,10 +782,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 "なし" @@ -791,13 +794,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" @@ -806,13 +809,13 @@ msgid "Advanced sector images" msgstr "アドバンスドセクターイメージ" msgid "Flux images" -msgstr "フラックスイメージ" +msgstr "Fluxイメージ" 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 "使用中のマシンをハードリセットしますか?" +msgstr "使用中のマシンをハード リセットしますか?" msgid "Are you sure you want to exit 86Box?" msgstr "86Boxを終了しますか?" @@ -842,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 "保存" @@ -853,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 "ハードウェアが利用できません" @@ -878,10 +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)ファイルとして保存されます。" +msgstr "PostScriptファイルをPDFに自動変換するにはlibgsが必要です。\n\n汎用PostScriptプリンターに送信された文書は、PostScript (.ps) ファイルとして保存されます。" msgid "Entering fullscreen mode" -msgstr "フルスクリーンに切り替えています" +msgstr "全画面モードを入力" msgid "Don't show this message again" msgstr "今後、このメッセージを表示しない" @@ -899,7 +902,7 @@ msgid "CD-ROM images" msgstr "CD-ROMイメージ" msgid "%hs Device Configuration" -msgstr "%hs デバイスの設定" +msgstr "%hs のデバイス設定" msgid "Monitor in sleep mode" msgstr "モニターのスリープモード" @@ -911,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 "続行" @@ -935,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 "実行を再開" @@ -944,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 "ハードリセット" @@ -965,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 "新規のディスクを追加" @@ -998,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 "ディスクイメージファイルが既に存在します" @@ -1022,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 "上書き" @@ -1043,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ファイル" @@ -1064,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" @@ -1181,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 bf9325675..ac4476ca8 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 설정" @@ -853,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 "하드웨어를 이용할 수 없습니다" @@ -1196,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 6b017dfb5..b24e338f4 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" @@ -853,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" @@ -1196,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 1771c1f4a..0db661b4f 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" @@ -853,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" @@ -1201,3 +1204,23 @@ msgstr "Falha ao inicializar o driver de rede" msgid "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 a45aa78c5..8f080e423 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" @@ -853,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" @@ -1196,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 cb14c193d..b0bcc0e1e 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.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" @@ -853,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\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 "Оборудование недоступно" @@ -1196,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/sk-SK.po b/src/qt/languages/sk-SK.po new file mode 100644 index 000000000..a8f60b861 --- /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 "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 "Unable to initialize SDL, SDL2.dll is required" +msgstr "Nastala chyba pri inicializácii knižnice SDL, je potreba SDL2.dll" + +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 83b0d6774..98a51d863 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" @@ -853,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" @@ -944,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" @@ -1196,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 551764016..0d6875eb8 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ı" @@ -853,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" @@ -1196,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 394a2905d..6f8ecac52 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" @@ -853,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\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 "Обладнання недоступне" @@ -1196,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 5858b5ec3..3d045b74e 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 "设置" @@ -533,7 +536,7 @@ msgid "&New..." msgstr "新建(&N)..." msgid "&Existing..." -msgstr "已有镜像(&E)..." +msgstr "已有映像(&E)..." msgid "&Remove" msgstr "移除(&R)" @@ -566,7 +569,7 @@ msgid "Type:" msgstr "类型:" msgid "Image Format:" -msgstr "镜像格式:" +msgstr "映像格式:" msgid "Block Size:" msgstr "块大小:" @@ -599,7 +602,7 @@ msgid "ISA RTC:" msgstr "ISA 实时时钟:" msgid "ISA Memory Expansion" -msgstr "ISA 内存扩充" +msgstr "ISA 内存扩展" msgid "Card 1:" msgstr "扩展卡 1:" @@ -647,10 +650,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 +671,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\" 不可用。将切换到其他可用机型。" @@ -803,10 +806,10 @@ msgid "Floppy %i (%s): %ls" msgstr "软盘 %i (%s): %ls" msgid "Advanced sector images" -msgstr "高级扇区镜像" +msgstr "高级扇区映像" msgid "Flux images" -msgstr "Flux 镜像" +msgstr "Flux 映像" msgid "Unable to initialize SDL, SDL2.dll is required" msgstr "无法初始化 SDL,需要 SDL2.dll" @@ -824,7 +827,7 @@ msgid "MO %i (%ls): %ls" msgstr "磁光盘 %i (%ls): %ls" msgid "MO images" -msgstr "磁光盘镜像" +msgstr "磁光盘映像" msgid "Welcome to 86Box!" msgstr "欢迎使用 86Box!" @@ -853,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 "硬件不可用" @@ -896,7 +899,7 @@ msgid "Don't reset" msgstr "不重置" msgid "CD-ROM images" -msgstr "光盘镜像" +msgstr "光盘映像" msgid "%hs Device Configuration" msgstr "%hs 设备配置" @@ -923,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 "初始化渲染器时出错" @@ -980,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 "无法读取文件" @@ -995,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 "请确定此文件已存在并可读取。" @@ -1016,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 "覆盖" @@ -1034,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)" @@ -1064,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 "父盘与子盘的时间戳不匹配" @@ -1196,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 cb414ce92..2d2ea473e 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 "音量增益" @@ -407,16 +410,16 @@ msgid "Joystick 4..." msgstr "搖桿 4..." msgid "Sound card 1:" -msgstr "音訊卡 1:" +msgstr "音效卡 1:" msgid "Sound card 2:" -msgstr "音訊卡 2:" +msgstr "音效卡 2:" msgid "Sound card 3:" -msgstr "音訊卡 3:" +msgstr "音效卡 3:" msgid "Sound card 4:" -msgstr "音訊卡 4:" +msgstr "音效卡 4:" msgid "MIDI Out Device:" msgstr "MIDI 輸出裝置:" @@ -557,7 +560,7 @@ msgid "Heads:" msgstr "磁頭(H):" msgid "Cylinders:" -msgstr "柱面(C):" +msgstr "磁柱(C):" msgid "Size (MB):" msgstr "大小 (MB):" @@ -853,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 "硬體不可用" @@ -1196,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 6f84beee5..ff4e7c4d2 100644 --- a/src/qt/macos_event_filter.mm +++ b/src/qt/macos_event_filter.mm @@ -17,13 +17,6 @@ extern int mouse_capture; 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 @@ CocoaEventFilter::~CocoaEventFilter() 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 @@ CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, || [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 @@ CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, 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 @@ CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, 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 @@ CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, } 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_cdrom.c b/src/qt/qt_cdrom.c index 6e28966b0..1facae486 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_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index eaa5e9566..6c7db0f3d 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_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index b640c086e..5dab101b8 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -321,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; @@ -511,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.ui b/src/qt/qt_harddiskdialog.ui index 84c557660..91499d2cb 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 55b7fa820..dda36917f 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.cpp b/src/qt/qt_hardwarerenderer.cpp index ee2ec07df..47f0de718 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -136,6 +136,22 @@ HardwareRenderer::initializeGL() m_context->swapBuffers(this); } +void +HardwareRenderer::paintOverGL() +{ + /* Context switching is needed to make use of QPainter to draw status bar icons in fullscreen. + Especially since it seems to be impossible to use QPainter on externally-created OpenGL contexts. */ + if (video_fullscreen && status_icons_fullscreen) { + m_context->makeCurrent(nullptr); + makeCurrent(); + QPainter painter(this); + drawStatusBarIcons(&painter); + painter.end(); + doneCurrent(); + m_context->makeCurrent(this); + } +} + void HardwareRenderer::paintGL() { diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index da23c4b05..1918cda18 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -53,6 +53,7 @@ public: { onResize(size().width(), size().height()); } + void paintOverGL() override; 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 e91cb9086..c363cd544 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++) { @@ -146,6 +147,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 +174,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 +186,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 +195,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 7789b48c4..139b99ca5 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 e667ae4eb..d7b115a64 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 daf13f72d..409a63248 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 */ @@ -135,6 +137,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 +194,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 +225,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 +289,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 +307,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 +338,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 != 6) + 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 ae6ff955e..e0252dd7a 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -117,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 @@ -191,15 +196,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); @@ -211,7 +207,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); @@ -253,8 +253,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); @@ -270,8 +268,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) { @@ -295,7 +305,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.)); @@ -330,9 +342,12 @@ MainWindow::MainWindow(QWidget *parent) ui->actionUpdate_status_bar_icons->setChecked(update_icons); ui->actionEnable_Discord_integration->setChecked(enable_discord); ui->actionApply_fullscreen_stretch_mode_when_maximized->setChecked(video_fullscreen_scale_maximized); + ui->actionShow_status_icons_in_fullscreen->setChecked(status_icons_fullscreen); #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 @@ -528,12 +543,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); @@ -581,6 +600,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); @@ -589,6 +611,15 @@ MainWindow::MainWindow(QWidget *parent) if (!vnc_enabled) video_setblit(qt_blit); + if (start_in_fullscreen) { + connect(ui->stackedWidget, &RendererStack::blit, 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); @@ -630,7 +661,7 @@ MainWindow::MainWindow(QWidget *parent) 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, [this](){}); + 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); @@ -677,6 +708,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 @@ -764,7 +809,6 @@ MainWindow::initRendererMonitorSlot(int monitor_index) secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); secondaryRenderer->setMouseTracking(true); } - connect(this, &MainWindow::pollMouse, secondaryRenderer.get(), &RendererStack::mousePoll, Qt::DirectConnection); } } @@ -816,10 +860,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 @@ -890,20 +930,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; @@ -1508,10 +1545,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(); @@ -1520,7 +1558,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(); @@ -1555,6 +1594,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) { @@ -1658,7 +1704,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); @@ -1705,22 +1751,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); @@ -1988,3 +2043,11 @@ void MainWindow::on_actionACPI_Shutdown_triggered() { acpi_pwrbut_pressed = 1; } + +void MainWindow::on_actionShow_status_icons_in_fullscreen_triggered() +{ + status_icons_fullscreen = !status_icons_fullscreen; + ui->actionShow_status_icons_in_fullscreen->setChecked(status_icons_fullscreen); + config_save(); +} + diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index d5a6b1967..553f9602c 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -39,7 +39,6 @@ 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); @@ -70,6 +69,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(); @@ -91,6 +91,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(); @@ -143,6 +144,7 @@ private slots: void on_actionCursor_Puck_triggered(); void on_actionACPI_Shutdown_triggered(); + void on_actionShow_status_icons_in_fullscreen_triggered(); private slots: void on_actionShow_non_primary_monitors_triggered(); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index b61a974c6..d682815bb 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -68,17 +68,19 @@ + + + + - - @@ -148,6 +150,7 @@ + @@ -177,6 +180,7 @@ + @@ -255,6 +259,7 @@ + @@ -262,6 +267,14 @@ + + + true + + + &Auto-pause on focus loss + + true @@ -585,6 +598,14 @@ &Integer scale + + + true + + + 4:&3 Integer scale + + true @@ -861,6 +882,14 @@ Cursor/Puck + + + true + + + Show status icons in fullscreen + + true diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index 10c505e3b..e24ad9aa1 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 7fb044fcc..c0437d810 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 0274bc44a..7ea28a4ce 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -36,13 +36,18 @@ #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 @@ -299,6 +304,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) { @@ -360,7 +371,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 +382,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 +408,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 +432,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 +450,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)" } }, }; } @@ -639,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); @@ -660,3 +670,75 @@ 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(); +} diff --git a/src/qt/qt_progsettings.ui b/src/qt/qt_progsettings.ui index fa0818652..16fb439be 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 c2b38cd52..05c35e09b 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -17,17 +17,24 @@ #include "qt_renderercommon.hpp" #include "qt_mainwindow.hpp" +#include "qt_machinestatus.hpp" #include #include #include #include +#include +#include +#include #include extern "C" { #include <86box/86box.h> +#include <86box/plat.h> #include <86box/video.h> + +int status_icons_fullscreen = 0; } RendererCommon::RendererCommon() = default; @@ -51,62 +58,129 @@ 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; + 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 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: - 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 { + 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(); +} + +void RendererCommon::drawStatusBarIcons(QPainter* painter) +{ + uint32_t x = 0; + auto prevcompositionMode = painter->compositionMode(); + painter->setCompositionMode(QPainter::CompositionMode::CompositionMode_SourceOver); + for (int i = 0; i < main_window->statusBar()->children().count(); i++) { + QLabel* label = qobject_cast(main_window->statusBar()->children()[i]); + if (label) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const QPixmap pixmap = label->pixmap(); +#elif QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) + const QPixmap pixmap = label->pixmap(Qt::ReturnByValue); +#else + const QPixmap pixmap = (label->pixmap() ? *label->pixmap() : QPixmap()); +#endif + if (!pixmap.isNull()) { + painter->setBrush(QColor::fromRgbF(0, 0, 0, 1.)); + painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, + pixmap.width(), pixmap.height() + 5, QColor::fromRgbF(0, 0, 0, .5)); + painter->drawPixmap(x + main_window->statusBar()->layout()->spacing() / 2, + painter->device()->height() - pixmap.height() - 3, pixmap); + x += pixmap.width(); + if (i <= main_window->statusBar()->children().count() - 3) { + painter->fillRect(x, painter->device()->height() - pixmap.height() - 5, + main_window->statusBar()->layout()->spacing(), pixmap.height() + 5, + QColor::fromRgbF(0, 0, 0, .5)); + x += main_window->statusBar()->layout()->spacing(); + } else + painter->fillRect(x, painter->device()->height() - pixmap.height() - 4, 4, + pixmap.height() + 4, QColor::fromRgbF(0, 0, 0, .5)); + } + } + } + if (main_window->status->getMessage().isEmpty() == false) { + auto curStatusMsg = main_window->status->getMessage(); + auto textSize = painter->fontMetrics().size(Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' ')); + painter->setPen(QColor(0, 0, 0, 127)); + painter->fillRect(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), + textSize.width(), textSize.height(), QColor(0, 0, 0, 127)); + painter->setPen(QColor(255, 255, 255, 255)); + painter->drawText(QRectF(painter->device()->width() - textSize.width(), painter->device()->height() - textSize.height(), + textSize.width(), textSize.height()), Qt::TextSingleLine, QChar(' ') + curStatusMsg + QChar(' ')); + } + painter->setCompositionMode(prevcompositionMode); } bool @@ -128,5 +202,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 34b28fb30..897240d27 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -38,8 +38,11 @@ public: 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 ee87dccb8..e5ed77ba7 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -49,37 +49,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 +87,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 +140,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 +161,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 +182,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 +202,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 +227,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 +243,6 @@ RendererStack::mouseMoveEvent(QMouseEvent *event) #endif } - void #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) RendererStack::enterEvent(QEnterEvent *event) @@ -280,7 +252,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 +261,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(); @@ -557,10 +529,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 df52a9542..c9d90869b 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -71,20 +71,12 @@ public: /* 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: @@ -96,7 +88,6 @@ 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(); private: void createRenderer(Renderer renderer); diff --git a/src/qt/qt_sdl.c b/src/qt/qt_sdl.c index 6d04acd25..15af4d7b6 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 29804c278..f9709c857 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 f9a6b8e14..c7cb99086 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 fb878b716..3ec61dfb7 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 5f2f81c58..fcb70f8c5 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -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 @@ -102,11 +102,6 @@ SettingsDisplay::onCurrentMachineChanged(int machineId) ui->comboBoxVideoSecondary->setEnabled(true); ui->pushButtonConfigureSecondary->setEnabled(true); } - if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_8514) - ibm8514_has_vga = 0; - if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_XGA) - xga_has_vga = 0; - ui->comboBoxVideo->setCurrentIndex(selectedRow); if (gfxcard[1] == 0) ui->pushButtonConfigureSecondary->setEnabled(false); @@ -115,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)); } @@ -128,12 +126,10 @@ SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() void SettingsDisplay::on_pushButtonConfigureXga_clicked() { - if (!xga_has_vga) { - if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { - DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast(Settings::settings)); - } else { - DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast(Settings::settings)); - } + if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { + DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast(Settings::settings)); + } else { + DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast(Settings::settings)); } } @@ -145,7 +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) { @@ -153,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) && !ibm8514_has_vga); - 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; - ui->checkBoxXga->setEnabled((hasIsa16 || has_MCA) && !xga_has_vga); - if (hasIsa16 || has_MCA) - ui->checkBoxXga->setChecked(xga_enabled); + 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->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked() && !xga_has_vga); + ui->checkBox8514->setEnabled((machineHasIsa16 || machineHasMca) && !videoCardHas8514); + if (machineHasIsa16 || machineHasMca) + ui->checkBox8514->setChecked(ibm8514_standalone_enabled && !videoCardHas8514); + + ui->checkBoxXga->setEnabled((machineHasIsa16 || machineHasMca) && !videoCardHasXga); + if (machineHasIsa16 || machineHasMca) + ui->checkBoxXga->setChecked(xga_standalone_enabled && !videoCardHasXga); + + ui->pushButtonConfigureXga->setEnabled((machineHasIsa16 || machineHasMca) && ui->checkBoxXga->isChecked() && !videoCardHasXga); int c = 2; @@ -184,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); @@ -208,7 +217,7 @@ SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) void SettingsDisplay::on_checkBoxXga_stateChanged(int state) { - ui->pushButtonConfigureXga->setEnabled((state == Qt::Checked) && !xga_has_vga); + ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked); } void diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index c34c7aa38..dfda43c40 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -61,6 +61,9 @@ + + 30 + 0 @@ -119,6 +122,9 @@ + + 30 + 0 diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 4d2f6e9f9..988f9e856 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 7a025e7a6..d7ad853b3 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 ef351e5e7..3ae20fee1 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 630fc705d..34d111e10 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; @@ -190,9 +190,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 8f4f46167..839461119 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 569d1f6c3..475730db9 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++; @@ -113,202 +127,206 @@ SettingsMachine::save() 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; - } + if (index >= 0) { + auto *model = ui->comboBoxMachine->model(); + int removeRows = model->rowCount(); - 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; + 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; - } + if (index >= 0) { + int machineId = ui->comboBoxMachine->currentData().toInt(); + const auto *device = machine_get_device(machineId); + ui->pushButtonConfigure->setEnabled((device != nullptr) && (device->config != nullptr)); - 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(); - 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; + 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); + 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)); + 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; - } + if (index >= 0) { + int machineId = ui->comboBoxMachine->currentData().toInt(); + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto *cpuFamily = &cpu_families[cpuFamilyId]; - 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(); - 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; + // 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; - } + 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; - // 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 ((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); - } else if (flags & CPU_REQUIRES_DYNAREC) { - ui->checkBoxDynamicRecompiler->setChecked(true); - ui->checkBoxDynamicRecompiler->setEnabled(false); - } else { - ui->checkBoxDynamicRecompiler->setChecked(cpu_use_dynarec); - ui->checkBoxDynamicRecompiler->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 - int machineId = ui->comboBoxMachine->currentData().toInt(); - auto *modelFpu = ui->comboBoxFPU->model(); - int removeRows = modelFpu->rowCount(); + // 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; + 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); + } +} + +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); } } - - modelFpu->removeRows(0, removeRows); - ui->comboBoxFPU->setEnabled(modelFpu->rowCount() > 1); - ui->comboBoxFPU->setCurrentIndex(-1); - ui->comboBoxFPU->setCurrentIndex(selectedFpuRow); - - 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 abb4f3014..9d0ec62ff 100644 --- a/src/qt/qt_settingsmachine.hpp +++ b/src/qt/qt_settingsmachine.hpp @@ -21,6 +21,9 @@ signals: 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 ee8a048f4..22ecc15df 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: - - - - - - Machine: + + + 30 - - - + + + + Memory: + + + + + + + 30 + + + + + + 0 @@ -74,18 +85,35 @@ 0 - - - - + + + 30 + - + 0 0 + + + + - Configure + PIT Mode: + + + + + + + 30 + + + + 0 + 0 + @@ -116,6 +144,9 @@ + + 30 + 0 @@ -136,6 +167,9 @@ + + 30 + 0 @@ -147,33 +181,6 @@ - - - - FPU: - - - - - - - - - - Wait states: - - - - - - - - - - Memory: - - - @@ -184,6 +191,65 @@ + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 30 + + + + + + + + 0 + 0 + + + + Configure + + + + + + + + + + Machine type: + + + + + + + Machine: + + + + + + + FPU: + + + diff --git a/src/qt/qt_settingsnetwork.cpp b/src/qt/qt_settingsnetwork.cpp index 5b5d1b1ee..2aa3705fd 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 d6681a65e..8f1eb5a79 100644 --- a/src/qt/qt_settingsnetwork.ui +++ b/src/qt/qt_settingsnetwork.ui @@ -51,6 +51,9 @@ + + 30 + 0 @@ -74,6 +77,9 @@ + + 30 + 0 @@ -97,6 +103,9 @@ + + 30 + 0 @@ -170,6 +179,9 @@ + + 30 + 0 @@ -193,6 +205,9 @@ + + 30 + 0 @@ -216,6 +231,9 @@ + + 30 + 0 @@ -283,6 +301,9 @@ + + 30 + 0 @@ -306,6 +327,9 @@ + + 30 + 0 @@ -329,6 +353,9 @@ + + 30 + 0 @@ -356,7 +383,7 @@ - VDE Socket + VDE Socket @@ -402,6 +429,9 @@ + + 30 + 0 @@ -425,6 +455,9 @@ + + 30 + 0 @@ -448,6 +481,9 @@ + + 30 + 0 diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index d168138a5..f662b644c 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" @@ -44,7 +45,9 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) 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->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); @@ -112,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++) { @@ -197,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 97e47c90e..feaa7a001 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 62a4b9308..af953a984 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 bb77046d2..f8b29dac5 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 c57dd3ca2..219333376 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 7a338aff5..bca870e5d 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 f792791c1..b4df4ff69 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 f85a09a0d..1d5ab0050 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.ui b/src/qt/qt_settingsstoragecontrollers.ui index 9fc0ea519..d67127e2d 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_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index a8c0229d3..ab9ed932d 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -24,6 +24,7 @@ extern "C" { #include <86box/86box.h> +#include <86box/plat.h> #include <86box/video.h> } @@ -113,6 +114,7 @@ SoftwareRenderer::onPaint(QPaintDevice *device) #endif painter.setCompositionMode(QPainter::CompositionMode_Plus); painter.drawImage(destination, *images[cur_image], source); + if (video_fullscreen && status_icons_fullscreen) drawStatusBarIcons(&painter); } std::vector> diff --git a/src/qt/qt_translations.qrc b/src/qt/qt_translations.qrc index 845099436..017354f82 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 22dad3fa1..47e6b48a2 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 73594ea9e..9227cdcb3 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 7961dd7f9..d4580d848 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 73eea9ad8..3ca091ae6 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,70 +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); - - window->checkFullscreenHotkey(); - } - } else { - if (rawKB.MakeCode == 0x1D) { - scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would - otherwise be E0 00 but that is invalid - anyway). - Also, take a potential mapping into - account. */ - } else - scancode = 0xFFFF; if (scancode != 0xFFFF) keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); + + window->checkFullscreenHotkey(); } } @@ -338,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 81b2c0d48..f687164ca 100644 --- a/src/qt/qt_winrawinputfilter.hpp +++ b/src/qt/qt_winrawinputfilter.hpp @@ -59,9 +59,6 @@ public: ~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 bc540fcf6..cdbf102b8 100644 --- a/src/qt/sdl_joystick.cpp +++ b/src/qt/sdl_joystick.cpp @@ -41,15 +41,15 @@ joystick_init() plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); 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); + 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); + 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); + 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; } } diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index e5d477296..7ee0e8227 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 @@ -98,8 +98,6 @@ 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) return; @@ -139,14 +137,11 @@ 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 @@ -450,7 +445,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 789712de5..5d6d95a0a 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 25d4de66c..e1751fd82 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 000000000..e55033172 --- /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 000000000..f06db9419 --- /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 dafa4ffda..1be6ec826 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 @@ common_motion: 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 @@ common_motion: } 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 @@ common_motion: } 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/scsi/scsi.c b/src/scsi/scsi.c index 1f1e6eafd..94c9048ef 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 2a1c23566..05b8b2726 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -152,13 +152,13 @@ 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; } } @@ -282,15 +282,12 @@ aha_param_len(void *priv) 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; @@ -716,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. */ @@ -725,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; } @@ -737,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; @@ -757,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; @@ -824,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) @@ -832,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; } @@ -844,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; } @@ -860,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; @@ -874,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 @@ -902,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) @@ -912,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); @@ -1028,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 */ @@ -1044,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 */ @@ -1064,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 */ @@ -1088,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 */ @@ -1100,6 +1101,8 @@ aha_init(const device_t *info) break; } + scsi_bus_set_speed(dev->bus, dev->ha_bps); + /* Initialize ROM BIOS if needed. */ aha_setbios(dev); diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 72c02ba1c..ac3b464a8 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -675,7 +675,7 @@ buslogic_cmds(void *priv) const HALocalRAM *HALR = &bl->LocalRAM; - FILE *f; + FILE *fp; uint16_t TargetsPresentMask = 0; uint32_t Offset; int i = 0; @@ -872,6 +872,7 @@ buslogic_cmds(void *priv) 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; @@ -890,11 +891,11 @@ buslogic_cmds(void *priv) 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: @@ -1232,9 +1233,7 @@ BuslogicPCIWrite(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x10: val &= 0xe0; val |= 1; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x11: case 0x12: @@ -1258,9 +1257,7 @@ BuslogicPCIWrite(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x14: val &= 0xe0; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x15: case 0x16: @@ -1532,16 +1529,16 @@ static void * buslogic_init(const device_t *info) { x54x_t *dev; - char *bios_rom_name; + 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 = NULL; + const char *autoscsi_rom_name = NULL; uint16_t autoscsi_rom_size = 0; uint8_t has_scam_rom; - char *scam_rom_name = NULL; + const char *scam_rom_name = NULL; uint16_t scam_rom_size = 0; - FILE *f; + FILE *fp; buslogic_data_t *bl; uint32_t bios_rom_addr; @@ -1709,9 +1706,10 @@ buslogic_init(const device_t *info) 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); @@ -1725,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 { @@ -1748,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 721e75c64..65417ebe3 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -41,6 +41,8 @@ #include <86box/scsi_cdrom.h> #include <86box/version.h> +#define IDE_ATAPI_IS_EARLY id->sc->pad0 + #pragma pack(push, 1) typedef struct gesn_cdb_t { uint8_t opcode; @@ -184,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); @@ -281,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 }, @@ -335,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 }, @@ -373,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 }, @@ -516,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); } @@ -541,37 +545,9 @@ 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; - - default: - break; - } - } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; + return (dev->tf->features & 1) ? 2 : 1; } return 0; @@ -581,96 +557,135 @@ static uint32_t scsi_cdrom_get_channel(void *priv, int channel) { 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 *priv, int channel) { 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)); + 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); - 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); + 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); - 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); - } + 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; } } @@ -730,37 +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]; - 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]; + 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; - } - } else { - 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; + 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; - - } + default: + break; + } + break; } return 0; @@ -800,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 @@ -842,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]) { @@ -883,9 +903,7 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) break; } } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; default: dev->packet_len = len; @@ -899,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; } @@ -932,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); @@ -961,67 +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; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + 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") || - !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")) { - 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") || - !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; + 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; - case 0xde: - 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")) { - bytes_per_second = 176.0 * 1024.0; - bytes_per_second *= (double) dev->drv->cur_speed; - } - break; - + fallthrough; default: bytes_per_second = scsi_cdrom_bus_speed(dev); if (bytes_per_second == 0.0) { @@ -1046,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 @@ -1054,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 @@ -1069,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 @@ -1088,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; @@ -1118,7 +1156,8 @@ 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 @@ -1143,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); @@ -1160,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); @@ -1244,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 @@ -1254,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 @@ -1521,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; } @@ -1620,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 @@ -1717,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; @@ -1739,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; @@ -1760,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]); } @@ -1813,14 +1853,20 @@ begin: 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); + break; } + fallthrough; case GPCMD_SET_SPEED: dev->drv->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; if (dev->drv->cur_speed < 1) @@ -1895,54 +1941,95 @@ begin: 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; + } + + 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; - 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; + 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; } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - + 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; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case GPCMD_READ_6: case GPCMD_READ_10: @@ -2045,14 +2132,24 @@ begin: 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); @@ -2123,21 +2220,26 @@ begin: 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; @@ -2149,7 +2251,7 @@ begin: 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. */ @@ -2430,87 +2532,181 @@ begin: 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); - 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 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); - else - scsi_cdrom_illegal_mode(dev); + break; + 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); + 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]; + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; - scsi_cdrom_buf_alloc(dev, 65536); + scsi_cdrom_buf_alloc(dev, 65536); - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); + if (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } + + 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_set_buf_len(dev, BufLen, &len); + + 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); - 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); + 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; + } + + 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); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - 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; + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + break; + default: + scsi_cdrom_illegal_opcode(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); + break; - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); + 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: @@ -2530,8 +2726,6 @@ begin: 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]; @@ -2580,7 +2774,6 @@ begin: case GPCMD_READ_SUBCHANNEL: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 0; max_len = cdb[7]; max_len <<= 8; @@ -2638,13 +2831,13 @@ begin: 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; } @@ -2658,66 +2851,120 @@ begin: 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; - - 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; - } - - /* 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) - 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); - - alloc_length = cdb[1] & 0x1f; - len = 10; - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - if (!alloc_length) { + 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); - 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); + dev->sony_vendor = 1; + + 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; + } + + /* 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) + 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); + 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); - scsi_cdrom_buf_alloc(dev, len); - len = MIN(len, alloc_length); + alloc_length = cdb[1] & 0x1f; + len = 10; - 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 (!dev->drv->ops) { + scsi_cdrom_not_ready(dev); + return; + } - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 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_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; + + 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; + } + + 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_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; @@ -2757,10 +3004,14 @@ begin: } 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: @@ -2790,46 +3041,77 @@ begin: 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: @@ -2877,14 +3159,14 @@ begin: 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 */ @@ -2910,35 +3192,33 @@ begin: 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; @@ -2947,32 +3227,32 @@ begin: 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 */ @@ -2980,23 +3260,29 @@ begin: 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; } } } @@ -3031,84 +3317,151 @@ atapi_out: 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); + 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; - dev->sony_vendor = !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403") ? 0 : 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: @@ -3128,14 +3481,24 @@ atapi_out: } 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); @@ -3174,84 +3537,149 @@ atapi_out: 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]; + 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]); @@ -3259,10 +3687,13 @@ atapi_out: 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)); @@ -3295,29 +3726,37 @@ atapi_out: 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); } @@ -3387,57 +3826,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); @@ -3452,11 +3904,18 @@ 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; @@ -3473,6 +3932,9 @@ scsi_cdrom_close(void *priv) { scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; + if (dev->tf) + free(dev->tf); + if (dev) free(dev); } @@ -3540,76 +4002,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; } } @@ -3633,6 +4116,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. */ @@ -3665,9 +4149,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]; @@ -3687,7 +4174,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; @@ -3697,12 +4189,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 4fce9f989..4442b2680 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -23,6 +23,7 @@ #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> @@ -37,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; @@ -140,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 600d9f6e3..39a69ea32 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); } } @@ -280,14 +346,166 @@ scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, } static void +scsi_disk_update_request_length(scsi_disk_t *dev, int len, int block_len) +{ + 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) { - dev->status = BUSY_STAT; - dev->phase = 1; - if (dev->packet_status == PHASE_COMPLETE) - dev->callback = 0.0; - else - dev->callback = -1.0; /* Speed depends on SCSI controller */ + 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 @@ -298,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) { @@ -305,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) { @@ -312,23 +544,48 @@ 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, UNUSED(int block_len), int alloc_len, int direction) +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 @@ -353,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) { @@ -397,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 @@ -407,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 @@ -419,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; } @@ -462,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 @@ -507,32 +835,16 @@ scsi_disk_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t all } static void -scsi_disk_set_buf_len(UNUSED(scsi_disk_t *dev), int32_t *BufLen, int32_t *src_len) +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); } } @@ -540,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; @@ -555,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; @@ -576,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], @@ -597,9 +917,7 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) scsi_disk_invalid_field(dev); return; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: @@ -610,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; } @@ -655,63 +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: @@ -722,75 +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) { @@ -801,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]; @@ -969,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 */ @@ -1020,6 +1381,10 @@ atapi_out: 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); @@ -1049,7 +1414,11 @@ atapi_out: 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 @@ -1073,6 +1442,7 @@ scsi_disk_phase_data_out(scsi_common_t *sc) 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; @@ -1101,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]) @@ -1148,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; @@ -1211,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); @@ -1242,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]; @@ -1260,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); } } } @@ -1280,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 8b0ae3c0c..f271df3ec 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -185,7 +185,7 @@ typedef struct ncr5380_t { #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; @@ -278,7 +278,7 @@ ncr_timer_on(ncr5380_t *ncr_dev, ncr_t *ncr, int callback) if (ncr_dev->type == 3) p *= 512.0; else - p *= 128.0; + p *= 144.0; } p += 1.0; @@ -639,7 +639,8 @@ ncr_write(uint16_t port, uint8_t val, void *priv) } } 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)) { + if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && + !timer_is_on(&ncr_dev->timer)) { ncr_log("Continuing DMA mode\n"); ncr_timer_on(ncr_dev, ncr, 0); } @@ -671,7 +672,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) if (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_log("DMA send timer start, enabled? = %i\n", timer_is_on(&ncr_dev->timer)); ncr_dev->t128.block_count = dev->buffer_length >> 9; ncr_dev->t128.block_loaded = 1; @@ -679,7 +680,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr_dev->t128.status |= 0x04; } } else { - if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer)) { memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); ncr_log("DMA send timer on\n"); @@ -693,7 +694,8 @@ 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); + ncr_log("DMA receive timer start, enabled? = %i, cdb[0] = %02x, buflen = %i\n", + timer_is_on(&ncr_dev->timer), ncr->command[0], dev->buffer_length); if (dev->buffer_length > 0) { memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); @@ -709,7 +711,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) timer_on_auto(&ncr_dev->timer, 0.02); } } else { - if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer)) { memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); ncr_log("DMA receive timer start\n"); @@ -1386,31 +1388,36 @@ t128_read(uint32_t addr, void *priv) 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) { + 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, 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)) 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); + 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.*/ } } @@ -1426,23 +1433,25 @@ t128_write(uint32_t addr, uint8_t val, void *priv) 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) { + 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) + } 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; @@ -1551,10 +1560,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); @@ -1633,7 +1646,7 @@ ncr_init(const device_t *info) ncr_log("%s\n", temp); ncr_reset(ncr_dev, &ncr_dev->ncr); - if (ncr_dev->type < 3 || ncr_dev->type == 4) { + if ((ncr_dev->type < 3) || (ncr_dev->type == 4)) { ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; ncr_dev->buffer_host_pos = 128; } else { @@ -1645,6 +1658,8 @@ ncr_init(const device_t *info) } 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 897f37d1d..42925338d 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -234,6 +234,7 @@ typedef struct ncr53c8xx_t { int waiting; uint8_t current_lun; + uint8_t irq_state; uint8_t istat; uint8_t dcmd; @@ -498,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"); } } @@ -534,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. */ @@ -1440,15 +1445,15 @@ ncr53c8xx_callback(void *priv) 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); } } @@ -2552,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; @@ -2618,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 3f30fdafc..674bbdabf 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -197,6 +197,7 @@ typedef struct esp_t { 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"); } } @@ -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; } } @@ -726,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; @@ -740,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++; } @@ -966,7 +963,7 @@ esp_callback(void *priv) } } - 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 @@ -1029,9 +1026,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) switch (saddr) { case ESP_TCHI: dev->tchi_written = 1; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case ESP_TCLO: case ESP_TCMID: esp_log("Transfer count regs %02x = %i\n", saddr, val); @@ -1061,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: @@ -1095,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); @@ -1464,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 @@ -1600,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; @@ -1657,7 +1651,6 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) return 2; } } - break; case 0x01: return 0x10; case 0x02: @@ -1842,7 +1835,7 @@ dc390_init(UNUSED(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; @@ -1872,14 +1865,16 @@ dc390_init(UNUSED(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; @@ -1892,6 +1887,16 @@ 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; @@ -1900,56 +1905,55 @@ ncr53c90_in(uint16_t port, void *priv) } } - 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) { const esp_t *dev = (esp_t *) priv; @@ -1957,7 +1961,7 @@ ncr53c90_mca_read(int port, void *priv) } 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[] = { @@ -1974,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. */ @@ -1999,20 +2003,20 @@ 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) { const esp_t *dev = (esp_t *) priv; @@ -2020,7 +2024,7 @@ ncr53c90_mca_feedb(void *priv) } static void * -ncr53c90_mca_init(UNUSED(const device_t *info)) +ncr53c9x_mca_init(UNUSED(const device_t *info)) { esp_t *dev; @@ -2034,14 +2038,16 @@ ncr53c90_mca_init(UNUSED(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; } @@ -2086,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 3b9f5108c..ba2817fe3 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; @@ -674,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; @@ -716,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; @@ -916,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); @@ -969,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; } @@ -1055,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 @@ -1081,6 +1082,7 @@ 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 @@ -1088,6 +1090,8 @@ spock_mca_read(int port, void *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]; } @@ -1118,10 +1122,14 @@ 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 * -spock_init(UNUSED(const device_t *info)) +spock_init(const device_t *info) { spock_t *scsi = malloc(sizeof(spock_t)); memset(scsi, 0x00, sizeof(spock_t)); @@ -1131,23 +1139,24 @@ spock_init(UNUSED(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 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); 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; 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); @@ -1155,15 +1164,18 @@ spock_init(UNUSED(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; } @@ -1218,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 0b9cb0281..6876e4385 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); + } } } @@ -486,9 +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); -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x05: /* Format Track, invalid since SCSI has no tracks */ case 0x0a: /* ???? */ case 0x0b: /* ???? */ @@ -1291,7 +1293,7 @@ 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); + 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 @@ -1340,24 +1342,27 @@ x54x_in(uint16_t port, void *priv) if (dev->flags & X54X_INT_GEOM_WRITABLE) ret = dev->Geometry; else { - 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; + 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; @@ -1415,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 @@ -1464,7 +1470,7 @@ 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; @@ -1771,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 15411d3e6..3140a7181 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -15,7 +15,7 @@ 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 diff --git a/src/sio/sio_82091aa.c b/src/sio/sio_82091aa.c index 346d2d435..cbe89c682 100644 --- a/src/sio/sio_82091aa.c +++ b/src/sio/sio_82091aa.c @@ -209,9 +209,9 @@ i82091aa_write(uint16_t port, uint8_t val, void *priv) 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 10250d602..275d9ae2e 100644 --- a/src/sio/sio_acc3221.c +++ b/src/sio/sio_acc3221.c @@ -416,7 +416,7 @@ acc3221_write(uint16_t addr, uint8_t val, void *priv) static uint8_t acc3221_read(uint16_t addr, void *priv) { - acc3221_t *dev = (acc3221_t *) priv; + const acc3221_t *dev = (acc3221_t *) priv; if (!(addr & 1)) return dev->reg_idx; diff --git a/src/sio/sio_ali5123.c b/src/sio/sio_ali5123.c index 25fb1aa65..78c585c11 100644 --- a/src/sio/sio_ali5123.c +++ b/src/sio/sio_ali5123.c @@ -428,10 +428,10 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) 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 01c41224a..38faf3c2c 100644 --- a/src/sio/sio_detect.c +++ b/src/sio/sio_detect.c @@ -47,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]); diff --git a/src/sio/sio_f82c710.c b/src/sio/sio_f82c710.c index fc0eb2aae..d4afb11da 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. */ @@ -230,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 3a1bcf5af..cb678427c 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> @@ -45,35 +47,67 @@ typedef struct 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; - - default: - 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 @@ -81,149 +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]; + } 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 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 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 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; - } 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)); - } + 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 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; - 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); - } - break; - case 3: - if (!dev->id && (valxor & 2)) - fdc_update_enh_mode(dev->fdc, (val & 2) ? 1 : 0); - 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; - - default: + case 0x29: + dev->regs[dev->cur_reg] = val & 0x0f; break; } } @@ -231,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; @@ -262,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; + dev->regs[0x1e] = 0x3c; /* Gameport controller. */ + dev->regs[0x20] = 0x3c; + dev->regs[0x21] = 0x3c; + dev->regs[0x22] = 0x3d; + 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 { fdc_reset(dev->fdc); - - lpt1_remove(); - lpt1_init(LPT1_ADDR); - - dev->regs[0x23] = (LPT1_ADDR >> 2); - - dev->regs[0x24] = (COM1_ADDR >> 2) & 0xfe; - dev->regs[0x25] = (COM2_ADDR >> 2) & 0xfe; + fdc37c669_fdc_handler(dev); } - dev->regs[0x26] = (2 << 4) | 3; - dev->regs[0x27] = (6 << 4) | (dev->id ? 5 : 7); - dev->regs[0x28] = (4 << 4) | 3; + + fdc37c669_uart_handler(dev, 0); + serial_set_clock_src(dev->uart[0], fdc37c669_uart_get_clock_src(dev, 0)); + + fdc37c669_uart_handler(dev, 1); + serial_set_clock_src(dev->uart[1], fdc37c669_uart_get_clock_src(dev, 1)); + + fdc37c669_lpt_handler(dev); dev->locked = 0; dev->rw_locked = 0; @@ -317,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); @@ -334,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, @@ -348,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 3cfa5a38d..871f3b1c8 100644 --- a/src/sio/sio_fdc37c67x.c +++ b/src/sio/sio_fdc37c67x.c @@ -71,7 +71,7 @@ make_port(fdc37c67x_t *dev, uint8_t ld) static uint8_t 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; } @@ -87,8 +87,8 @@ fdc37c67x_auxio_write(UNUSED(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]; @@ -316,6 +316,7 @@ fdc37c67x_write(uint16_t port, uint8_t val, void *priv) case 0x26: case 0x27: fdc37c67x_sio_handler(dev); + break; default: break; diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index 95e0dfdd7..22b88615d 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 @@ -230,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) diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 0330297fb..4acbfeff5 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -93,7 +93,7 @@ make_port_sec(fdc37c93x_t *dev, uint8_t ld) static uint8_t 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; } @@ -109,8 +109,8 @@ fdc37c93x_auxio_write(UNUSED(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]; @@ -257,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: diff --git a/src/sio/sio_fdc37m60x.c b/src/sio/sio_fdc37m60x.c index 190e65453..38a163538 100644 --- a/src/sio/sio_fdc37m60x.c +++ b/src/sio/sio_fdc37m60x.c @@ -163,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]; diff --git a/src/sio/sio_it8661f.c b/src/sio/sio_it8661f.c deleted file mode 100644 index 5e5ccb655..000000000 --- a/src/sio/sio_it8661f.c +++ /dev/null @@ -1,353 +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> -#include <86box/plat_unused.h> - -#define LDN dev->regs[7] - -typedef struct it8661f_t { - fdc_t *fdc_controller; - serial_t *uart[2]; - - uint8_t index; - uint8_t regs[256]; - uint8_t device_regs[6][256]; - int unlocked; - int 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; - - default: - 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; - - default: - 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; - - default: - 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; - - default: - 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; - - default: - 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(UNUSED(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 000000000..74e79bbed --- /dev/null +++ b/src/sio/sio_it86x1f.c @@ -0,0 +1,871 @@ +/* + * 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; + if (val) + pclog("IT86x1F: Warning: ISAPnP mode enabled.\n"); + 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 656b36d92..ab7f8597e 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -35,11 +35,13 @@ #include <86box/fdc.h> #include <86box/sio.h> #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]; @@ -50,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 & 1] = val; + 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; + } + + (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 @@ -222,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; @@ -234,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)) @@ -256,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)) @@ -273,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]); @@ -297,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) { @@ -368,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; @@ -383,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" @@ -398,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 @@ -419,9 +475,11 @@ pc87306_init(UNUSED(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); - pc87306_reset(dev); + dev->gpio[0] = dev->gpio[1] = 0xff; + + pc87306_reset_common(dev); io_sethandler(0x02e, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, dev); @@ -436,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 e66467d62..63e19c03d 100644 --- a/src/sio/sio_pc87307.c +++ b/src/sio/sio_pc87307.c @@ -67,11 +67,11 @@ 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: @@ -139,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]; @@ -456,9 +456,9 @@ pc87307_write(uint16_t port, uint8_t val, void *priv) 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; diff --git a/src/sio/sio_pc87309.c b/src/sio/sio_pc87309.c index edd1fb0b8..d10cb3e0b 100644 --- a/src/sio/sio_pc87309.c +++ b/src/sio/sio_pc87309.c @@ -77,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]; @@ -351,9 +351,9 @@ pc87309_write(uint16_t port, uint8_t val, void *priv) 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 d567bd4d5..075b819ff 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 @@ -42,7 +40,8 @@ #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; @@ -64,8 +63,8 @@ pc87310_log(const char *fmt, ...) typedef struct pc87310_t { uint8_t tries; - uint8_t ide_function; - uint8_t reg; + uint8_t flags; + uint8_t regs[2]; fdc_t *fdc; serial_t *uart[2]; } pc87310_t; @@ -83,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: @@ -111,23 +112,59 @@ 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; + temp = (dev->regs[1] >> 2) & 0x07; - // 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); + /* - 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); } } @@ -136,61 +173,63 @@ 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); + + pc87310_log("[%04X:%08X] [W] %02X = %02X (%i)\n", CS, cpu_state.pc, port, val, dev->tries); - // second write to config register if (dev->tries) { - valxor = val ^ dev->reg; - dev->tries = 0; - dev->reg = val; - // first write to config register - } else { + /* 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); + } + } else + /* First write to config register. */ dev->tries++; - return; - } - - pc87310_log("SIO: written %01X\n", val); - - /* 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); - } - } - return; } uint8_t @@ -198,12 +237,13 @@ 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; } @@ -211,22 +251,18 @@ pc87310_read(UNUSED(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); -#if 0 - ide_pri_enable(); -#endif } static void @@ -240,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; } @@ -280,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 143712692..9740753d1 100644 --- a/src/sio/sio_pc87311.c +++ b/src/sio/sio_pc87311.c @@ -122,7 +122,7 @@ pc87311_write(uint16_t addr, uint8_t val, void *priv) static uint8_t 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]; } diff --git a/src/sio/sio_prime3b.c b/src/sio/sio_prime3b.c index 32be854c7..c93630516 100644 --- a/src/sio/sio_prime3b.c +++ b/src/sio/sio_prime3b.c @@ -143,7 +143,7 @@ prime3b_write(uint16_t addr, uint8_t val, void *priv) static uint8_t 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 160f23aab..b19f861bf 100644 --- a/src/sio/sio_prime3c.c +++ b/src/sio/sio_prime3c.c @@ -207,7 +207,7 @@ prime3c_write(uint16_t addr, uint8_t val, void *priv) static uint8_t 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_um8669f.c b/src/sio/sio_um8669f.c index 256c614ae..136b1add6 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,11 +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 */ @@ -61,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 */ @@ -87,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 }, } @@ -113,15 +150,14 @@ um8669f_log(const char *fmt, ...) #endif typedef struct um8669f_t { - int locked; - int 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; @@ -178,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); @@ -186,6 +238,7 @@ 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; @@ -207,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); } @@ -222,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); @@ -250,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; @@ -268,9 +324,9 @@ um8669f_close(void *priv) } static void * -um8669f_init(UNUSED(const device_t *info)) +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)); @@ -284,6 +340,10 @@ um8669f_init(UNUSED(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, @@ -298,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, @@ -307,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_w83787f.c b/src/sio/sio_w83787f.c index 1870741c7..33cfc6311 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -374,6 +374,8 @@ w83787f_read(uint16_t port, void *priv) static void w83787f_reset(w83787f_t *dev) { + uint16_t hefere = dev->reg_init & 0x0100; + lpt1_remove(); lpt1_init(LPT1_ADDR); lpt1_irq(LPT1_IRQ); @@ -410,7 +412,7 @@ w83787f_reset(w83787f_t *dev) dev->regs[0x07] = 0xF5; dev->regs[0x09] = dev->reg_init & 0xff; dev->regs[0x0a] = 0x1F; - dev->regs[0x0c] = 0x2C; + dev->regs[0x0c] = 0x0C | (hefere >> 3); dev->regs[0x0d] = 0xA3; gameport_remap(dev->gameport, 0); @@ -420,7 +422,7 @@ w83787f_reset(w83787f_t *dev) w83787f_lpt_handler(dev); - dev->key = 0x89; + dev->key = 0x88 | (hefere >> 8); w83787f_remap(dev); @@ -456,17 +458,31 @@ w83787f_init(const device_t *info) dev->ide_start = !!(info->local & 0x40); - dev->reg_init = info->local & 0x0f; + dev->reg_init = info->local & 0x010f; w83787f_reset(dev); return dev; } +const device_t w83787f_88h_device = { + .name = "Winbond W83787F/IF Super I/O", + .internal_name = "w83787f", + .flags = 0, + .local = 0x0009, + .init = w83787f_init, + .close = w83787f_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t w83787f_device = { .name = "Winbond W83787F/IF Super I/O", .internal_name = "w83787f", .flags = 0, - .local = 0x09, + .local = 0x0109, .init = w83787f_init, .close = w83787f_close, .reset = NULL, @@ -480,7 +496,7 @@ const device_t w83787f_ide_device = { .name = "Winbond W83787F/IF Super I/O (With IDE)", .internal_name = "w83787f_ide", .flags = 0, - .local = 0x19, + .local = 0x0119, .init = w83787f_init, .close = w83787f_close, .reset = NULL, @@ -494,7 +510,7 @@ const device_t w83787f_ide_en_device = { .name = "Winbond W83787F/IF Super I/O (With IDE Enabled)", .internal_name = "w83787f_ide_en", .flags = 0, - .local = 0x59, + .local = 0x0159, .init = w83787f_init, .close = w83787f_close, .reset = NULL, @@ -508,7 +524,7 @@ const device_t w83787f_ide_sec_device = { .name = "Winbond W83787F/IF Super I/O (With Secondary IDE)", .internal_name = "w83787f_ide_sec", .flags = 0, - .local = 0x39, + .local = 0x0139, .init = w83787f_init, .close = w83787f_close, .reset = NULL, diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index ec4f8823b..d6672ac18 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_re snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c) + snd_optimc.c midi_opl4.c midi_opl4_yrw801.c) if(OPENAL) if(VCPKG_TOOLCHAIN) diff --git a/src/sound/midi.c b/src/sound/midi.c index 1a9c24657..c5dbd666f 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. @@ -102,6 +100,7 @@ static const MIDI_OUT_DEVICE devices[] = { #ifdef USE_RTMIDI { &rtmidi_output_device }, #endif + { &opl4_midi_device }, { NULL } // clang-format on }; @@ -153,7 +152,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 +175,7 @@ midi_out_device_get_from_internal_name(char *s) void midi_out_device_init(void) { - if (devices[midi_output_device_current].device) + if ((midi_output_device_current > 0) && devices[midi_output_device_current].device) device_add(devices[midi_output_device_current].device); midi_output_device_last = midi_output_device_current; } @@ -271,7 +270,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 +293,7 @@ midi_in_device_get_from_internal_name(char *s) void midi_in_device_init(void) { - if (midi_in_devices[midi_input_device_current].device) + if ((midi_input_device_current > 0) && midi_in_devices[midi_input_device_current].device) device_add(midi_in_devices[midi_input_device_current].device); midi_input_device_last = midi_input_device_current; } diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 08aefe16c..c1b9956d0 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -1,32 +1,31 @@ /* some code borrowed from scummvm */ -#ifdef USE_FLUIDSYNTH -# include -# include -# include -# include -# include -# ifdef __unix__ -# include -# endif -# define FLUIDSYNTH_NOT_A_DLL -# include +#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> +#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 +#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 +#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); @@ -167,19 +166,19 @@ fluidsynth_init(UNUSED(const device_t *info)) data->synth = new_fluid_synth(data->settings); const char *sound_font = device_get_config_string("sound_font"); -# ifdef __unix__ +#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 +#endif data->sound_font = fluid_synth_sfload(data->synth, sound_font, 1); if (device_get_config_int("chorus")) { -# ifndef USE_OLD_FLUIDSYNTH_API +#ifndef USE_OLD_FLUIDSYNTH_API fluid_synth_chorus_on(data->synth, -1, 1); -# else +#else fluid_synth_set_chorus_on(data->synth, 1); -# endif +#endif int chorus_voices = device_get_config_int("chorus_voices"); double chorus_level = device_get_config_int("chorus_level") / 100.0; @@ -192,48 +191,48 @@ fluidsynth_init(UNUSED(const device_t *info)) else chorus_waveform = FLUID_CHORUS_MOD_TRIANGLE; -# ifndef USE_OLD_FLUIDSYNTH_API +#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 +#else fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform); -# endif +#endif } else -# ifndef USE_OLD_FLUIDSYNTH_API +#ifndef USE_OLD_FLUIDSYNTH_API fluid_synth_chorus_on(data->synth, -1, 0); -# else +#else fluid_synth_set_chorus_on(data->synth, 0); -# endif +#endif if (device_get_config_int("reverb")) { -# ifndef USE_OLD_FLUIDSYNTH_API +#ifndef USE_OLD_FLUIDSYNTH_API fluid_synth_reverb_on(data->synth, -1, 1); -# else +#else fluid_synth_set_reverb_on(data->synth, 1); -# endif +#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; double reverb_width = device_get_config_int("reverb_width") / 10.0; double reverb_level = device_get_config_int("reverb_level") / 100.0; -# ifndef USE_OLD_FLUIDSYNTH_API +#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 +#else fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level); -# endif +#endif } else -# ifndef USE_OLD_FLUIDSYNTH_API +#ifndef USE_OLD_FLUIDSYNTH_API fluid_synth_reverb_on(data->synth, -1, 0); -# else +#else fluid_synth_set_reverb_on(data->synth, 0); -# endif +#endif int interpolation = device_get_config_int("interpolation"); int fs_interpolation = FLUID_INTERP_4THORDER; @@ -499,4 +498,3 @@ const device_t fluidsynth_device = { .config = fluidsynth_config }; -#endif /*USE_FLUIDSYNTH*/ diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c new file mode 100644 index 000000000..9708db150 --- /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 000000000..96822b9af --- /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/munt/CMakeLists.txt b/src/sound/munt/CMakeLists.txt index 37d9e07cc..d0438aa5b 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 7b64f97f9..f91a81828 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 5888b97b2..f536f2ab8 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/resid-fp/sid.cc b/src/sound/resid-fp/sid.cc index 6f7544423..ad72d9d51 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 6e9f93f1d..d302db6ae 100644 --- a/src/sound/snd_ac97_codec.c +++ b/src/sound/snd_ac97_codec.c @@ -25,6 +25,7 @@ #include <86box/device.h> #include <86box/io.h> #include <86box/snd_ac97.h> +#include <86box/plat_fallthrough.h> static const struct { const device_t *device; @@ -417,9 +418,7 @@ rate: /* Writable only if VRA/VRM is set. */ /* Get actual previous value. */ prev = dev->vendor_reg_pages[(i << 3) | ((reg & 0x0e) >> 1)]; } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x5a ... 0x5e: /* Vendor Reserved */ case 0x70 ... 0x7a: @@ -586,7 +585,7 @@ ac97_codec_init(const device_t *info) 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, (info->local >> 24) & 0xff, (info->local >> 16) & 0xff, (info->local >> 8) & 0xff, info->local & 0xff); + 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; } diff --git a/src/sound/snd_ac97_via.c b/src/sound/snd_ac97_via.c index e074d17e2..ceac42387 100644 --- a/src/sound/snd_ac97_via.c +++ b/src/sound/snd_ac97_via.c @@ -73,7 +73,8 @@ typedef struct _ac97_via_ { uint8_t regs_linear[256]; }; } codec_shadow[2]; - int slot; + uint8_t pci_slot; + uint8_t irq_state; int irq_pin; ac97_codec_t *codec[2][2]; @@ -115,8 +116,8 @@ 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 @@ -182,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 diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 33379289d..d2a05fd6f 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 @@ -241,9 +242,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 10: if (ad1848->type < AD1848_TYPE_CS4235) break; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 8: updatefreq = 1; diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 984a06ea9..71cbbcaa6 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -182,18 +182,18 @@ adgold_update_irq_status(adgold_t *adgold) adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; } -void +int adgold_getsamp_dma(adgold_t *adgold, int channel) { int temp; dma_set_drq(adgold->dma, 1); if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127)) - return; + return 2; temp = dma_channel_read(adgold->dma); if (temp == DMA_NODATA) { - return; + return 1; } adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; @@ -207,6 +207,8 @@ adgold_getsamp_dma(adgold_t *adgold, int channel) adgold_update_irq_status(adgold); dma_set_drq(adgold->dma, 0); } + + return 0; } void @@ -377,8 +379,16 @@ adgold_write(uint16_t addr, uint8_t val, void *priv) adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { - adgold_getsamp_dma(adgold, 0); - adgold_getsamp_dma(adgold, 1); + if (adgold_getsamp_dma(adgold, 0)) { + adgold->adgold_mma_fifo_end[0] = 0; + adgold->adgold_mma_fifo_start[0] = 0; + break; + } + if (adgold_getsamp_dma(adgold, 1)) { + adgold->adgold_mma_fifo_end[1] = 0; + adgold->adgold_mma_fifo_start[1] = 0; + break; + } } if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { adgold->adgold_mma_status &= ~0x01; @@ -392,7 +402,11 @@ adgold_write(uint16_t addr, uint8_t val, void *priv) } } else { while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { - adgold_getsamp_dma(adgold, 0); + if (adgold_getsamp_dma(adgold, 0)) { + adgold->adgold_mma_fifo_end[0] = 0; + adgold->adgold_mma_fifo_start[0] = 0; + break; + } } if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { adgold->adgold_mma_status &= ~0x01; @@ -502,7 +516,11 @@ adgold_write(uint16_t addr, uint8_t val, void *priv) if (adgold->adgold_mma_regs[1][0xc] & 1) { while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) { - adgold_getsamp_dma(adgold, 1); + if (adgold_getsamp_dma(adgold, 1)) { + adgold->adgold_mma_fifo_end[1] = 0; + adgold->adgold_mma_fifo_start[1] = 0; + break; + } } } } @@ -675,10 +693,14 @@ adgold_mma_poll(adgold_t *adgold, int channel) } if (adgold->adgold_mma_regs[channel][0xc] & 1) { - adgold_getsamp_dma(adgold, channel); + if (adgold_getsamp_dma(adgold, channel)) { + adgold->adgold_mma_fifo_end[channel] = 0; + adgold->adgold_mma_fifo_start[channel] = 0; + return; + } } if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < adgold->adgold_mma_intpos[channel] && !(adgold->adgold_mma_status & 0x01)) { - adgold->adgold_mma_status |= 1 << channel; + adgold->adgold_mma_status |= (1 << channel); adgold_update_irq_status(adgold); } } @@ -692,8 +714,8 @@ adgold_timer_poll(void *priv) { adgold_t *adgold = (adgold_t *) priv; - /*A small timer period will result in hangs.*/ - timer_on_auto(&adgold->adgold_mma_timer_count, 4.88964); + /*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) { if ((adgold->adgold_midi_ctrl & 0x3f) != 0x3f) { @@ -888,9 +910,9 @@ adgold_filter_cd_audio(int channel, double *buffer, void *priv) } 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; @@ -908,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; @@ -930,7 +952,7 @@ adgold_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) void * adgold_init(UNUSED(const device_t *info)) { - FILE *f; + FILE *fp; int c; double out; adgold_t *adgold = malloc(sizeof(adgold_t)); @@ -980,11 +1002,11 @@ adgold_init(UNUSED(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; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index b2fe90ca0..1405d8769 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -53,6 +53,7 @@ typedef struct es1371_t { uint32_t base_addr; uint8_t int_line; + uint8_t irq_state; uint16_t pmcsr; @@ -120,7 +121,7 @@ typedef struct es1371_t { int cd_vol_l; int cd_vol_r; - int card; + uint8_t pci_slot; int pos; int16_t buffer[SOUNDBUFLEN * 2]; @@ -235,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 @@ -325,21 +326,15 @@ es1371_reset(void *priv) /* 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 */ - /* Bit 13 is supposed to be always 1 on ES1371, and one of the GPIO interrupt - flags on ES1373. The 5.12.01 WDM driver only initializes its GPIO interrupt - handler on chip revisions which support this feature (1371 >= 0x04 and 5880 - all), but calls it anyway during interrupt servicing regardless of revision, - crashing on ES1371 as soon as an interrupt arrives while that bit is set. - Pending hardware research because actual early ES1371 cards are rare. */ - dev->int_status = 0x7fffdec0; + dev->int_status = 0x7ffffec0; /* 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 */ @@ -347,15 +342,15 @@ es1371_reset(void *priv) /* 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 */ @@ -363,7 +358,7 @@ es1371_reset(void *priv) /* 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 */ @@ -371,17 +366,17 @@ es1371_reset(void *priv) /* 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 @@ -1632,7 +1627,7 @@ es1371_pci_read(int func, int addr, void *priv) return 0x00; case 0x08: - return 0x02; /* Revision ID - 0x02 is supposed to be early Ensoniq-branded ES1371 but unconfirmed */ + return 0x02; /* Revision ID - 0x02 is actual Ensoniq-branded ES1371 */ case 0x09: return 0x00; /* Multimedia audio device */ case 0x0a: @@ -2059,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); @@ -2106,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); diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index b4a4dd238..80d668599 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -968,7 +968,7 @@ azt2316a_get_buffer(int32_t *buffer, int len, void *priv) static void * azt_init(const device_t *info) { - FILE *f; + FILE *fp; char *fn = NULL; int i; int loaded_from_eeprom = 0; @@ -986,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; @@ -1273,7 +1273,7 @@ azt_close(void *priv) { 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) { @@ -1283,18 +1283,18 @@ azt_close(void *priv) } /* 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); diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index c3d93aee9..359563b99 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -34,6 +34,7 @@ #include <86box/gameport.h> #include <86box/nmi.h> #include <86box/ui.h> +#include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> enum { @@ -96,7 +97,8 @@ typedef struct _cmi8x38_ { uint16_t mpu_base; uint8_t pci_regs[256]; uint8_t io_regs[256]; - int slot; + uint8_t pci_slot; + uint8_t irq_state; sb_t *sb; void *gameport; @@ -147,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); } } @@ -467,9 +469,7 @@ 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; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0xf1 ... 0xf7: return; @@ -822,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; @@ -1472,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_cs423x.c b/src/sound/snd_cs423x.c index 8be3b6b33..fad1d76b9 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -36,6 +36,7 @@ #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 @@ -170,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); } } @@ -299,9 +300,7 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) switch (val) { case 0x55: /* Disable PnP Key */ dev->pnp_enable = 0; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x5a: /* Update Hardware Configuration Data */ cs423x_pnp_enable(dev, 0, 1); diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index ad00461f1..22435c065 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -2168,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) { diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 1a4265c4c..d0af5c564 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -16,7 +16,10 @@ #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 { @@ -97,12 +100,18 @@ typedef struct gus_t { int irqnext; + uint8_t irq_state; + uint8_t midi_irq_state; + pc_timer_t timer_1; pc_timer_t timer_2; + uint8_t type; + int irq; int dma; int irq_midi; + int dma2; uint16_t base; int latch_enable; @@ -135,9 +144,9 @@ typedef struct gus_t { 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; @@ -156,8 +165,10 @@ double vol16bit[4096]; void gus_update_int_status(gus_t *gus) { - 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; @@ -186,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 + intr_pending = 0; + } else { + 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); - } 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 ((gus->irq_midi != -1) && (gus->irq_midi != gus->irq)) { + if (midi_intr_pending) + picint(1 << gus->irq_midi); + else + picintc(1 << gus->irq_midi); } } @@ -405,7 +427,8 @@ writegus(uint16_t addr, uint8_t val, void *priv) 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*/ @@ -415,15 +438,28 @@ writegus(uint16_t addr, uint8_t val, void *priv) 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); @@ -431,7 +467,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) break; } gus->dmaaddr++; - gus->dmaaddr &= 0xFFFFF; + gus->dmaaddr &= 0xfffff; c++; if (dma_result & DMA_OVER) break; @@ -445,18 +481,25 @@ writegus(uint16_t addr, uint8_t val, void *priv) 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; @@ -472,28 +515,20 @@ writegus(uint16_t addr, uint8_t val, void *priv) 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); @@ -518,7 +553,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) 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: @@ -572,14 +607,24 @@ writegus(uint16_t addr, uint8_t val, void *priv) } 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; @@ -626,9 +671,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) else if (gus->irq != -1) picint(1 << gus->irq); } -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x20d: gus->sb_2xc = val; break; @@ -640,20 +683,24 @@ writegus(uint16_t addr, uint8_t val, void *priv) 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 @@ -708,9 +755,11 @@ readgus(uint16_t addr, void *priv) 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; @@ -829,15 +878,16 @@ readgus(uint16_t addr, void *priv) 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; 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 @@ -890,7 +940,7 @@ readgus(uint16_t addr, void *priv) #ifdef OLD_NMI_BEHAVIOR nmi = 0; #endif - /*FALLTHROUGH*/ + fallthrough; case 0x389: val = gus->ad_data; break; @@ -996,21 +1046,41 @@ gus_poll_wave(void *priv) 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) @@ -1113,30 +1183,30 @@ gus_get_buffer(int32_t *buffer, int len, void *priv) 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; @@ -1154,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; @@ -1173,6 +1243,105 @@ 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(UNUSED(const device_t *info)) { @@ -1180,7 +1349,7 @@ gus_init(UNUSED(const device_t *info)) 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); @@ -1205,6 +1374,8 @@ gus_init(UNUSED(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); @@ -1213,11 +1384,13 @@ gus_init(UNUSED(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); @@ -1252,7 +1425,7 @@ gus_speed_changed(void *priv) 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 } @@ -1358,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_mpu401.c b/src/sound/snd_mpu401.c index d9e51df29..a8c9d3e3c 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 @@ -105,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; @@ -120,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); @@ -133,8 +144,10 @@ 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 @@ -412,15 +425,16 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) } 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: @@ -430,14 +444,14 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) 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); @@ -580,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 */ @@ -660,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; @@ -734,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; @@ -1080,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) @@ -1122,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)) { @@ -1382,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: @@ -1414,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; @@ -1469,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; @@ -1600,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; } diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index 6ed697bf3..e4131f1fe 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -1657,4 +1657,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 c6cf13a33..0f996f6bc 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -51,7 +51,7 @@ enum { class YMFMChipBase { public: - YMFMChipBase(uint32_t clock, fm_type type, UNUSED(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) @@ -98,7 +98,7 @@ public: 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; @@ -139,7 +139,7 @@ public: 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]); @@ -150,12 +150,20 @@ public: { 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]; } } } @@ -167,12 +175,20 @@ public: 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; } @@ -306,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; } @@ -381,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", @@ -425,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, @@ -444,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_sb.c b/src/sound/snd_sb.c index ae0cebabf..b2a629079 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -520,6 +520,48 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv) *buffer = c * output_gain; } +void +sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv) +{ + const sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + double c; + double spk = mixer->speaker; + double master = channel ? mixer->master_r : mixer->master_l; + int32_t bass = channel ? mixer->bass_r : mixer->bass_l; + int32_t treble = channel ? mixer->treble_r : mixer->treble_l; + double bass_treble; + double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L); + + if (mixer->output_filter) + c = (low_fir_sb16(2, channel, *buffer) * spk) / 3.0; + else + c = ((*buffer) * spk) / 3.0; + c *= master; + + /* This is not exactly how one does bass/treble controls, but the end result is like it. + A better implementation would reduce the CPU usage. */ + if (bass != 8) { + bass_treble = sb_bass_treble_4bits[bass]; + + if (bass > 8) + c += (low_iir(2, channel, c) * bass_treble); + else if (bass < 8) + c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble)); + } + + if (treble != 8) { + bass_treble = sb_bass_treble_4bits[treble]; + + if (treble > 8) + c += (high_iir(2, channel, c) * bass_treble); + else if (treble < 8) + c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble)); + } + + *buffer = c * output_gain; +} + void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *priv) { @@ -743,6 +785,8 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) SoundBlaster 16 sets bit 7 if previous mixer index invalid. Status bytes initially 080h on startup for all but level bytes (SB16). */ + sb_log("CT1745: [W] %02X = %02X\n", mixer->index, val); + if (mixer->index == 0) { /* Reset: Changed defaults from -14dB to 0dB */ @@ -764,12 +808,25 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x44] = mixer->regs[0x45] = 0x80; mixer->regs[0x46] = mixer->regs[0x47] = 0x80; + /* 0x43 = Mic AGC (Automatic Gain Control?) according to Linux's sb.h. + NSC LM4560 datasheet: Bit 0: 1 = Enable, 0 = Disable; + Another source says this: Bit 0: 0 = AGC on (default), 1 = Fixed gain of 20 dB. */ mixer->regs[0x43] = 0x00; + mixer->regs[0x49] = mixer->regs[0x4a] = 0x80; + mixer->regs[0x83] = 0xff; sb->dsp.sb_irqm8 = 0; sb->dsp.sb_irqm16 = 0; 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; @@ -820,31 +877,37 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) Note: Registers 80h and 81h are Read-only for PnP boards. */ case 0x80: - if (val & 0x01) - sb_dsp_setirq(&sb->dsp, 2); - if (val & 0x02) - sb_dsp_setirq(&sb->dsp, 5); - if (val & 0x04) - sb_dsp_setirq(&sb->dsp, 7); - if (val & 0x08) - sb_dsp_setirq(&sb->dsp, 10); + if (!sb->pnp) { + if (val & 0x01) + sb_dsp_setirq(&sb->dsp, 2); + if (val & 0x02) + sb_dsp_setirq(&sb->dsp, 5); + if (val & 0x04) + sb_dsp_setirq(&sb->dsp, 7); + if (val & 0x08) + sb_dsp_setirq(&sb->dsp, 10); + } break; case 0x81: /* The documentation is confusing. sounds as if multple dma8 channels could be set. */ - if (val & 0x01) - sb_dsp_setdma8(&sb->dsp, 0); - if (val & 0x02) - sb_dsp_setdma8(&sb->dsp, 1); - if (val & 0x08) - sb_dsp_setdma8(&sb->dsp, 3); - if (val & 0x20) - sb_dsp_setdma16(&sb->dsp, 5); - if (val & 0x40) - sb_dsp_setdma16(&sb->dsp, 6); - if (val & 0x80) - sb_dsp_setdma16(&sb->dsp, 7); + if (!sb->pnp) { + if (val & 0x01) + sb_dsp_setdma8(&sb->dsp, 0); + else if (val & 0x02) + sb_dsp_setdma8(&sb->dsp, 1); + else if (val & 0x08) + sb_dsp_setdma8(&sb->dsp, 3); + + sb_dsp_setdma16(&sb->dsp, 4); + if (val & 0x20) + sb_dsp_setdma16(&sb->dsp, 5); + else if (val & 0x40) + sb_dsp_setdma16(&sb->dsp, 6); + else if (val & 0x80) + sb_dsp_setdma16(&sb->dsp, 7); + } break; case 0x83: @@ -854,13 +917,46 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) 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; @@ -916,7 +1012,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) if ((mixer->index >= 0x30) && (mixer->index <= 0x47)) ret = mixer->regs[mixer->index]; - else + else { switch (mixer->index) { case 0x00: ret = mixer->regs[mixer->index]; @@ -1018,22 +1114,24 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) case 7: ret |= 0x80; break; - - default: - break; } break; case 0x82: /* The Interrupt status register, addressed as register 82h on the Mixer register map, - is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, - in which case it should chain to the previous routine. */ + is used by the ISR to determine whether the interrupt is meant for it or for some + other ISR, in which case it should chain to the previous routine. */ /* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */ /* 0x02000 DSP v4.04, 0x4000 DSP v4.05, 0x8000 DSP v4.12. I haven't seen this making any difference, but I'm keeping it for now. */ /* If QEMU is any indication, then the values are actually 0x20, 0x40, and 0x80. */ - temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | ((sb->dsp.sb_irq401) ? 4 : 0) | 0x40; - ret = temp; + /* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */ + temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | + ((sb->dsp.sb_irq401) ? 4 : 0); + if (sb->dsp.sb_type >= SBAWE32) + ret = temp | 0x80; + else + ret = temp | 0x40; break; case 0x83: @@ -1055,20 +1153,28 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) 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: @@ -1076,6 +1182,9 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) break; } + sb_log("CT1745: [R] %02X = %02X\n", mixer->index, ret); + } + sb_log("CT1745: read REG%02X: %02X\n", mixer->index, ret); return ret; @@ -1086,9 +1195,6 @@ sb_ct1745_mixer_reset(sb_t *sb) { sb_ct1745_mixer_write(4, 0, sb); sb_ct1745_mixer_write(5, 0, sb); - - sb->mixer_sb16.regs[0xfd] = 16; - sb->mixer_sb16.regs[0xfe] = 6; } uint8_t @@ -1375,6 +1481,45 @@ sb_16_reply_mca_write(int port, uint8_t val, void *priv) 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) { @@ -1454,14 +1599,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+) */ @@ -1481,6 +1632,22 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) } } +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; + } +} + static void sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { @@ -1926,13 +2093,15 @@ sb_16_init(UNUSED(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) { @@ -1956,6 +2125,8 @@ sb_16_init(UNUSED(const device_t *info)) sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); @@ -1968,6 +2139,10 @@ sb_16_init(UNUSED(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; } @@ -1981,12 +2156,16 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); + sb_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)); @@ -2003,6 +2182,8 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) sb->pos_regs[0] = 0x38; sb->pos_regs[1] = 0x51; + sb->gameport_addr = 0x200; + return sb; } @@ -2012,16 +2193,21 @@ sb_16_pnp_init(UNUSED(const device_t *info)) sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0x00, sizeof(sb_t)); + sb->pnp = 1; + sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; sb->mixer_sb16.output_filter = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t)); @@ -2033,7 +2219,7 @@ sb_16_pnp_init(UNUSED(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); @@ -2043,8 +2229,102 @@ sb_16_pnp_init(UNUSED(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; @@ -2059,6 +2339,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; @@ -2069,43 +2351,47 @@ 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 * @@ -2128,6 +2414,8 @@ sb_awe32_init(UNUSED(const device_t *info)) sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); + sb_dsp_setdma16_supported(&sb->dsp, 1); + sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); if (sb->opl_enabled) { @@ -2151,6 +2439,8 @@ sb_awe32_init(UNUSED(const device_t *info)) sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); @@ -2165,6 +2455,10 @@ sb_awe32_init(UNUSED(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; } @@ -2176,16 +2470,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)); @@ -2200,25 +2500,25 @@ 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); 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: @@ -2227,11 +2527,11 @@ sb_awe32_pnp_init(const device_t *info) 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); } } @@ -2260,10 +2560,13 @@ 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; @@ -2940,6 +3243,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)", @@ -2958,6 +3268,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)", @@ -3008,6 +3325,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)", @@ -3221,6 +3545,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)", @@ -3271,6 +3602,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)", @@ -3341,6 +3679,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)", @@ -3407,6 +3752,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)", @@ -3465,6 +3817,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)", @@ -3599,7 +3958,7 @@ 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, @@ -3609,6 +3968,76 @@ const device_t sb_16_device = { .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, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .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 8c6d4146d..6fc7815ab 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -25,6 +25,7 @@ #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 @@ -64,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] = { @@ -114,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; @@ -422,40 +423,131 @@ sb_8_write_dma(void *priv, uint8_t val) return dma_channel_write(dsp->sb_8_dmanum, val) == DMA_NODATA; } +/* + Supported High DMA Translation Channel + ---------------------------------------------------- + 0 0 0 First 8-bit + 0 0 1 First 8-bit + 0 1 0 Second 8-bit + 0 1 1 Second 8-bit + 1 0 0 First 8-bit + 1 0 1 First 8-bit + 1 1 0 16-bit + 1 1 1 Second 8-bit + */ int sb_16_read_dma(void *priv) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; + int temp, ret = 0; + int dma_flags, dma_ch = dsp->sb_16_dmanum; - return dma_channel_read(dsp->sb_16_dmanum); + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) + ret = dma_channel_read(dma_ch); + else { + if (dsp->sb_16_dma_enabled) { + /* High DMA channel enabled, either translation is enabled or + 16-bit transfers are not supported. */ + if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) + dma_ch = dsp->sb_16_8_dmanum; + } else + /* High DMA channel disabled, always use the first 8-bit channel. */ + dma_ch = dsp->sb_8_dmanum; + temp = dma_channel_read(dma_ch); + ret = temp; + if ((temp != DMA_NODATA) && !(temp & DMA_OVER)) { + temp = dma_channel_read(dma_ch); + if (temp == DMA_NODATA) + ret = DMA_NODATA; + else { + dma_flags = temp & DMA_OVER; + temp &= ~DMA_OVER; + ret |= (temp << 8) | dma_flags; + } + } + } + + return ret; } int sb_16_write_dma(void *priv, uint16_t val) { const sb_dsp_t *dsp = (sb_dsp_t *) priv; + int temp, ret = 0; + int dma_ch = dsp->sb_16_dmanum; + + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) + ret = dma_channel_write(dma_ch, val) == DMA_NODATA; + else { + if (dsp->sb_16_dma_enabled) { + /* High DMA channel enabled, either translation is enabled or + 16-bit transfers are not supported. */ + if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) + dma_ch = dsp->sb_16_8_dmanum; + } else + /* High DMA channel disabled, always use the first 8-bit channel. */ + dma_ch = dsp->sb_8_dmanum; + temp = dma_channel_write(dma_ch, val & 0xff); + ret = temp; + if ((temp != DMA_NODATA) && (temp != DMA_OVER)) { + temp = dma_channel_write(dma_ch, val >> 8); + ret = temp; + } + } - return dma_channel_write(dsp->sb_16_dmanum, val) == DMA_NODATA; + return ret; } void 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) { @@ -478,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; @@ -488,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); @@ -600,9 +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; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + 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); @@ -613,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); @@ -671,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; @@ -684,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; @@ -697,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; @@ -710,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; @@ -789,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; @@ -800,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); @@ -885,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 @@ -926,6 +1020,7 @@ sb_exec_command(sb_dsp_t *dsp) */ default: + sb_dsp_log("Unknown DSP command: %02X\n", dsp->sb_command); break; } @@ -940,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) { @@ -992,6 +1091,9 @@ sb_write(uint16_t a, uint8_t v, void *priv) } } break; + + default: + break; } } @@ -1001,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) { @@ -1065,9 +1171,9 @@ sb_read(uint16_t a, void *priv) } 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); @@ -1090,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); @@ -1151,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)); diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index 693c3afc3..0537cd09a 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -88,15 +88,20 @@ speaker_update(void) void speaker_get_buffer(int32_t *buffer, int len, UNUSED(void *priv)) { - int32_t val; + double val_l, val_r; speaker_update(); if (!speaker_mute) { for (int c = 0; c < len * 2; c += 2) { - val = speaker_buffer[c >> 1]; - buffer[c] += val; - buffer[c + 1] += val; + val_l = val_r = (double) speaker_buffer[c >> 1]; + /* Apply PC speaker volume and filters */ + if (filter_pc_speaker != NULL) { + filter_pc_speaker(0, &val_l, filter_pc_speaker_p); + filter_pc_speaker(1, &val_r, filter_pc_speaker_p); + } + buffer[c] += (int32_t) val_l; + buffer[c + 1] += (int32_t) val_r; } } diff --git a/src/sound/sound.c b/src/sound/sound.c index 542528ccb..ed7f821e0 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -77,7 +77,10 @@ static volatile int cdaudioon = 0; static int cd_thread_enable = 0; static void (*filter_cd_audio)(int channel, double *buffer, void *priv) = NULL; -static void *filter_cd_audio_p = NULL; +static void *filter_cd_audio_p = NULL; + +void (*filter_pc_speaker)(int channel, double *buffer, void *priv) = NULL; +void *filter_pc_speaker_p = NULL; static const device_t sound_none_device = { .name = "None", @@ -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); @@ -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); } @@ -441,6 +447,15 @@ sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv } } +void +sound_set_pc_speaker_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv) +{ + if ((filter_pc_speaker == NULL) || (filter == NULL)) { + filter_pc_speaker = filter; + filter_pc_speaker_p = priv; + } +} + void sound_poll(UNUSED(void *priv)) { @@ -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/ymfm/ymfm.h b/src/sound/ymfm/ymfm.h index bc0cf8b6c..4f8ba1243 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 @@ public: { // 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 14c1aa965..55cdd643d 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 499bfceef..bb91c5dc0 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 544bbe89a..c72badb57 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 053ad9770..388162dfe 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 3467c0ddf..e6f6fa5ea 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 adeefd79f..a5ec912aa 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 000000000..0df3c0343 --- /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/timer.c b/src/timer.c index e863c2f21..fa8376bde 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; + 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; - return; + 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; } - - /*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; - } - - 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,8 +126,11 @@ 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_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); } @@ -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 ede0d5bb6..a7e4786be 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 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 +* Mon Oct 16 2023 Robert de Rooy 4.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 59671d0f9..9e2c5dc88 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 b56022474..cfa824313 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -21,6 +21,10 @@ #include #include +#ifdef __APPLE__ +# include "macOSXGlue.h" +#endif + #include <86box/86box.h> #include <86box/mem.h> #include <86box/rom.h> @@ -41,10 +45,6 @@ #include <86box/ui.h> #include <86box/gdbstub.h> -#ifdef __APPLE__ -# include "macOSXGlue.h" -#endif - static int first_use = 1; static uint64_t StartingTime; static uint64_t Frequency; @@ -60,6 +60,7 @@ extern wchar_t sdl_win_title[512]; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; joystick_t joystick_state[MAX_JOYSTICKS]; int joysticks_present; +int status_icons_fullscreen = 0; /* unused. */ SDL_mutex *blitmtx; SDL_threadID eventthread; static int exit_event = 0; @@ -191,6 +192,7 @@ dynld_module(const char *name, dllimp_t *table) { dllimp_t *imp; void *modhandle = dlopen(name, RTLD_LAZY | RTLD_GLOBAL); + if (modhandle) { for (imp = table; imp->name != NULL; imp++) { if ((*(void **) imp->func = dlsym(modhandle, imp->name)) == NULL) { @@ -199,6 +201,7 @@ dynld_module(const char *name, dllimp_t *table) } } } + return modhandle; } @@ -310,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) { @@ -394,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; } @@ -416,6 +430,7 @@ plat_get_ticks_common(void) { uint64_t EndingTime; uint64_t ElapsedMicroseconds; + if (first_use) { Frequency = SDL_GetPerformanceFrequency(); StartingTime = SDL_GetPerformanceCounter(); @@ -423,6 +438,7 @@ plat_get_ticks_common(void) } EndingTime = SDL_GetPerformanceCounter(); ElapsedMicroseconds = ((EndingTime - StartingTime) * 1000000) / Frequency; + return ElapsedMicroseconds; } @@ -447,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 @@ -463,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] == '\\') { @@ -500,6 +519,7 @@ volatile int cpu_thread_run = 1; void ui_sb_set_text_w(wchar_t *wstr) { + /* No-op. */ } int @@ -623,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; @@ -668,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"); } @@ -688,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); @@ -698,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. @@ -726,6 +741,7 @@ local_strsep(char **str, const char *sep) { char *s = *str; char *end; + if (!s) return NULL; end = s + strcspn(s, sep); @@ -734,6 +750,7 @@ local_strsep(char **str, const char *sep) else end = 0; *str = end; + return s; } @@ -743,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); @@ -763,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); @@ -776,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)) @@ -790,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); @@ -808,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 @@ -830,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) { @@ -870,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) { @@ -884,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) { @@ -962,7 +994,10 @@ monitor_thread(void *param) printf( "%s v%s [%s] [%s, %s]\n\n" "An emulator of old computers\n" - "Authors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\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) { @@ -988,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; @@ -1030,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); @@ -1050,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); @@ -1070,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); @@ -1090,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); @@ -1121,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(); @@ -1158,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. */ @@ -1169,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: @@ -1182,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; @@ -1191,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; @@ -1232,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; @@ -1244,6 +1291,7 @@ main(int argc, char **argv) case SDL_RENDER_TARGETS_RESET: { extern void sdl_reinit_texture(void); + sdl_reinit_texture(); break; } @@ -1251,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]; @@ -1323,6 +1372,13 @@ 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); +} + /* Converts back the language code to LCID */ void plat_language_code_r(uint32_t lcid, char *outbuf, int len) @@ -1334,15 +1390,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) { @@ -1359,9 +1421,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 7ba247108..424f1a9a3 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. diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 4cf723b00..3ba8c1ae0 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 61f23c345..d80f8a1e7 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/upi42.c b/src/upi42.c index 8348b32e4..50f5c44c9 100644 --- a/src/upi42.c +++ b/src/upi42.c @@ -916,7 +916,7 @@ timer: 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; @@ -1056,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 0ed98fc12..6bdc8e6c0 100644 --- a/src/usb.c +++ b/src/usb.c @@ -20,17 +20,14 @@ #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 @@ -51,98 +48,6 @@ 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 *priv) { @@ -231,724 +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 *priv) { const usb_t *dev = (usb_t *) priv; uint8_t ret = 0x00; -#ifdef ENABLE_USB_LOG - uint32_t old_addr = addr; -#endif 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 *priv) -{ - return ohci_mmio_read(addr, priv) | (ohci_mmio_read(addr + 1, priv) << 8); -} - -static uint32_t -ohci_mmio_readl(uint32_t addr, void *priv) -{ - return ohci_mmio_readw(addr, priv) | (ohci_mmio_readw(addr + 2, priv) << 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(UNUSED(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; - - default: - break; - } - 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 *priv) { 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: + case 0x0c: + dev->ohci_mmio[addr] &= ~(val & 0x7f); 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); + case 0x0d: + case 0x0e: return; - case OHCI_aHcInterruptEnable + 1: - case OHCI_aHcInterruptEnable + 2: + case 0x0f: + dev->ohci_mmio[addr] &= ~(val & 0x40); 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); + case 0x3b: + dev->ohci_mmio[addr] = (val & 0x80); 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); + case 0x39: + case 0x41: + dev->ohci_mmio[addr] = (val & 0x3f); return; - case OHCI_aHcInterruptDisable + 1: - case OHCI_aHcInterruptDisable + 2: + case 0x45: + dev->ohci_mmio[addr] = (val & 0x0f); 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); + case 0x3a: + case 0x3e: + case 0x3f: + case 0x42: + case 0x43: + case 0x46: + case 0x47: + case 0x48: + case 0x4a: return; - case OHCI_aHcInterruptStatus: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x7f); - return; - case OHCI_aHcInterruptStatus + 1: - case OHCI_aHcInterruptStatus + 2: - return; - case OHCI_aHcInterruptStatus + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x40); - return; - case OHCI_aHcFmRemaining + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x80); - return; - case OHCI_aHcFmRemaining + 1: - case OHCI_aHcPeriodicStart + 1: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x3f); - return; - case OHCI_aHcLSThreshold + 1: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (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: - 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] & 0x04) && (old & 0x04)) + dev->ohci_mmio[addr + 2] |= 0x04; #if 0 - 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] & 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; + 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 + 2: - case OHCI_aHcRhPortStatus2 + 2: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x1f); + case 0x56: + case 0x5a: + dev->ohci_mmio[addr] &= ~(val & 0x1f); return; - case OHCI_aHcRhPortStatus1 + 3: - case OHCI_aHcRhPortStatus2 + 3: - 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; default: break; } - dev->ohci_mmio[addr >> 2].b[addr & 3] = val; -} - -static void -ohci_mmio_writew(uint32_t addr, uint16_t val, void *priv) -{ - ohci_mmio_write(addr, val & 0xff, priv); - ohci_mmio_write(addr + 1, val >> 8, priv); -} - -static void -ohci_mmio_writel(uint32_t addr, uint32_t val, void *priv) -{ - ohci_mmio_writew(addr, val & 0xffff, priv); - ohci_mmio_writew(addr + 2, val >> 16, priv); + dev->ohci_mmio[addr] = val; } void @@ -962,71 +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 (uint8_t 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; - - default: - break; - } - return 0xff; -} - -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; - - default: - break; - } - return; } static void @@ -1034,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 @@ -1060,40 +398,39 @@ usb_close(void *priv) } static void * -usb_init_ext(UNUSED(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; + memset(dev->uhci_io, 0x00, 128); + dev->uhci_io[0x0c] = 0x40; + dev->uhci_io[0x10] = dev->uhci_io[0x12] = 0x80; - 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, + 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); - - mem_mapping_disable(&dev->ohci_mmio_mapping); - - 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); - 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 3d3d2d466..638837757 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_mach8.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_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) -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/vid_8514a.c b/src/video/vid_8514a.c index ccc530e3b..864a88978 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -34,6 +34,8 @@ #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 "cpu.h" @@ -63,30 +65,16 @@ ibm8514_log(const char *fmt, ...) #define READ_PIXTRANS_WORD(cx, n) \ if ((cmd <= 1) || (cmd == 5)) { \ - if (dev->local) { \ - temp = svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } 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); \ - } \ + 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 (dev->local) { \ - temp = svga->vram[(dev->accel.dest + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[(dev->accel.dest + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } 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); \ - } \ + temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \ } #define READ(addr, dat) \ - if (dev->local) { \ - if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - dat = vram_w[(addr) & (svga->vram_mask >> 1)]; \ - } else { \ - dat = (svga->vram[(addr) & (svga->vram_mask)]); \ - } \ + if (dev->bpp) { \ + dat = vram_w[(addr) & (dev->vram_mask >> 1)]; \ } else { \ dat = (dev->vram[(addr) & (dev->vram_mask)]); \ } @@ -158,13 +146,13 @@ ibm8514_log(const char *fmt, ...) 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)); \ @@ -176,7 +164,7 @@ ibm8514_log(const char *fmt, ...) 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; \ @@ -188,31 +176,26 @@ ibm8514_log(const char *fmt, ...) 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) \ - if (dev->local) { \ - if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - vram_w[((addr)) & (svga->vram_mask >> 1)] = dat; \ - svga->changedvram[(((addr)) & (svga->vram_mask >> 1)) >> 11] = changeframecount; \ - } else { \ - svga->vram[((addr)) & (svga->vram_mask)] = dat; \ - svga->changedvram[(((addr)) & (svga->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_has_vga = 0; +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; @@ -226,7 +209,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; @@ -238,18 +221,18 @@ ibm8514_cpu_dest(svga_t *svga) } void -ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(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) { @@ -462,16 +445,18 @@ regular_nibble: 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) { dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; - } else { + } else dev->accel.cur_y = val & 0x7ff; - } break; case 0x82e9: case 0xc2e9: @@ -482,11 +467,10 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) 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: @@ -500,6 +484,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; @@ -519,6 +504,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; @@ -536,9 +522,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) case 0x92e8: if (len != 1) dev->test = val; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0xd2e8: if (len == 1) dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; @@ -563,6 +547,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: @@ -581,8 +566,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; @@ -864,7 +852,8 @@ 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) { ibm8514_accel_out_fifo(svga, port, val, len); @@ -964,25 +953,49 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) break; case 0x42e8: - if (len == 1) { - dev->subsys_stat &= ~val; - } else { - dev->subsys_stat &= ~(val & 0xff); + old = dev->subsys_stat; + if ((val & 0xff) & 1) + dev->subsys_stat &= ~1; + if ((val & 0xff) & 2) + dev->subsys_stat &= ~2; + if ((val & 0xff) & 4) + dev->subsys_stat &= ~4; + if ((val & 0xff) & 8) + dev->subsys_stat &= ~8; + if (len != 1) { + old = dev->subsys_cntl; dev->subsys_cntl = (val >> 8); + if ((old ^ dev->subsys_cntl) & 1) + dev->subsys_stat |= 1; + if ((old ^ dev->subsys_cntl) & 2) + dev->subsys_stat |= 2; + if ((old ^ dev->subsys_cntl) & 4) + dev->subsys_stat |= 4; + if ((old ^ dev->subsys_cntl) & 8) + dev->subsys_stat |= 8; } break; case 0x42e9: if (len == 1) { + 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; + dev->accel.advfunc_cntl = val & 0x0f; + dev->on[0] = val & 0x01; + vga_on = !dev->on[0]; ibm8514_log("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); svga_recalctimings(svga); break; @@ -997,6 +1010,7 @@ static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; + ibm8514_accel_out(port, val, svga, 1); } @@ -1004,27 +1018,28 @@ static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv) { 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; + 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; @@ -1053,9 +1068,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 { @@ -1073,6 +1089,20 @@ 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) { temp = dev->test; @@ -1140,6 +1170,7 @@ static uint8_t ibm8514_accel_inb(uint16_t port, void *priv) { svga_t *svga = (svga_t *) priv; + return ibm8514_accel_in(port, svga, 1); } @@ -1147,13 +1178,14 @@ static uint16_t ibm8514_accel_inw(uint16_t port, void *priv) { 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; @@ -1168,11 +1200,17 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t ibm8514_accel_start(count, cpu_input, mix_dat, cpu_dat, svga, len); } +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) + void 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; - uint16_t *vram_w = (uint16_t *)svga->vram; + 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; @@ -1181,7 +1219,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat 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 = ((svga->bpp == 8) || (svga->bpp == 24)) ? 0x80 : 0x8000; + 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; @@ -1191,10 +1229,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat 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; - uint16_t poly_src = 0; + int and3 = dev->accel.cur_x & 3; - if ((svga->bpp == 8) || (svga->bpp == 24)) { + if (!dev->bpp) { compare &= 0xff; frgd_color &= 0xff; bkgd_color &= 0xff; @@ -1213,19 +1250,18 @@ 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 ((svga->bpp == 15) || (svga->bpp == 16)) { + if (dev->bpp) { if ((dev->accel.cmd & 0x200) && (count == 2)) count >>= 1; } @@ -1340,9 +1376,9 @@ 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, 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; + 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); + 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) { @@ -1356,7 +1392,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -1402,7 +1438,8 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } 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) { + 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; @@ -1440,7 +1477,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -1527,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 >= 0x600) { + if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - } - if (dev->accel.cur_y >= 0x600) { + + 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) { @@ -1595,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; @@ -1613,6 +1650,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat default: break; } + } READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); @@ -1692,7 +1730,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -1785,7 +1823,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.temp_cnt--; mix_dat >>= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -1794,70 +1832,34 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat 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: + if (dev->accel.cmd & 0x40) { + if (dev->accel.cmd & 0x80) dev->accel.cy++; - break; - case 0xe0: - dev->accel.cy++; - break; + else + dev->accel.cy--; - default: - break; + 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--; + + 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--; @@ -1913,79 +1915,42 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + 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: - 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: + if (dev->accel.cmd & 0x40) { + if (dev->accel.cmd & 0x80) dev->accel.cy++; - break; - case 0xe0: - dev->accel.cy++; - break; + else + dev->accel.cy--; - default: - break; + 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--; + + 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--; @@ -2019,12 +1984,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) - dev->accel.dest = (dev->accel.ge_offset << 2) + (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.fill_state = 0; + dev->accel.dest = dev->accel.cy * dev->pitch; if (cmd == 4) dev->accel.cmd |= 2; @@ -2070,8 +2033,8 @@ 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; - if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) + 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; @@ -2085,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) { @@ -2194,7 +2160,7 @@ rect_fill_pix: mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2226,15 +2192,14 @@ rect_fill_pix: 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); @@ -2265,7 +2230,11 @@ rect_fill_pix: 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; } @@ -2319,7 +2288,7 @@ rect_fill_pix: mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2347,10 +2316,10 @@ rect_fill_pix: else dev->accel.cy--; - if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) - dev->accel.dest = (dev->accel.ge_offset << 2) + (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.dest = dev->accel.cy * dev->pitch; dev->accel.sy--; return; @@ -2402,7 +2371,7 @@ rect_fill_pix: } } mix_dat >>= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2439,10 +2408,10 @@ rect_fill_pix: else dev->accel.cy--; - if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) - dev->accel.dest = (dev->accel.ge_offset << 2) + (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.dest = dev->accel.cy * dev->pitch; dev->accel.sy--; return; @@ -2497,8 +2466,14 @@ rect_fill_pix: 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; } @@ -2516,8 +2491,14 @@ rect_fill_pix: 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; } @@ -2546,7 +2527,7 @@ rect_fill_pix: } mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2567,8 +2548,13 @@ rect_fill_pix: 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; } @@ -2587,8 +2573,13 @@ rect_fill_pix: 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; } @@ -2648,7 +2639,7 @@ rect_fill_pix: mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -2672,7 +2663,11 @@ rect_fill_pix: 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; } @@ -2745,7 +2740,11 @@ rect_fill: 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; @@ -2756,7 +2755,7 @@ rect_fill: } 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; } @@ -2812,7 +2811,11 @@ rect_fill: 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) { @@ -2824,69 +2827,53 @@ rect_fill: } } } 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; - - default: - break; - } - - READ(dev->accel.dest + dev->accel.cx, poly_src); - if (dev->accel.multifunc[0x0a] & 2) { - poly_src = ((poly_src & wrt_mask) == wrt_mask); - } else { - poly_src = ((poly_src & rd_mask_polygon) == rd_mask_polygon); - } - - if (poly_src) { + 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, dest_dat); + old_dest_dat = dest_dat; if (dev->accel.fill_state) { - 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 (!(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 { + 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); + } + + 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))) { + 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++; @@ -2894,21 +2881,24 @@ rect_fill: 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; @@ -2924,13 +2914,17 @@ rect_fill: 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); + } } } @@ -2944,11 +2938,12 @@ rect_fill: 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) @@ -2956,7 +2951,11 @@ rect_fill: 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) { @@ -2972,17 +2971,25 @@ rect_fill: } 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.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.oldcy = dev->accel.cy; - 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; @@ -2995,134 +3002,200 @@ rect_fill: } } - 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 = cpu_dat; - break; - case 3: - src_dat = 0; - break; + 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; - default: - 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); + default: + break; + } - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - 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); + + 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; - if ((svga->bpp == 15) || (svga->bpp == 16)) - cpu_dat >>= 16; - else - 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++; - break; - case 0xe0: - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy++; - break; - - default: - break; + 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; - dev->accel.sy++; + 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; + + 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; + 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--; + } } - break; + } + break; - case 6: /*BitBlt*/ + case 6: /*BitBlt*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { dev->accel.x_count = 0; @@ -3131,12 +3204,12 @@ rect_fill: dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; - dev->accel.dx = dev->accel.destx_distp; - dev->accel.dy = dev->accel.desty_axstp; + dev->accel.dx = dev->accel.destx; + dev->accel.dy = dev->accel.desty; - if (dev->accel.destx_distp >= 0x600) + if (dev->accel.destx >= 0x600) dev->accel.dx |= ~0x5ff; - if (dev->accel.desty_axstp >= 0x600) + if (dev->accel.desty >= 0x600) dev->accel.dy |= ~0x5ff; dev->accel.cx = dev->accel.cur_x; @@ -3149,6 +3222,7 @@ rect_fill: 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) { @@ -3213,6 +3287,7 @@ bitblt_pix: 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); @@ -3221,7 +3296,7 @@ bitblt_pix: mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -3258,7 +3333,7 @@ bitblt_pix: dev->accel.cy--; } - dev->accel.src = 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; @@ -3311,7 +3386,7 @@ bitblt_pix: } } mix_dat >>= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -3346,8 +3421,8 @@ bitblt_pix: dev->accel.cx = dev->accel.cur_x; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - dev->accel.dx = dev->accel.destx_distp; - if (dev->accel.destx_distp >= 0x600) + dev->accel.dx = dev->accel.destx; + if (dev->accel.destx >= 0x600) dev->accel.dx |= ~0x5ff; } } @@ -3377,6 +3452,7 @@ bitblt_pix: } 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); @@ -3422,7 +3498,7 @@ bitblt_pix: } mix_dat <<= 1; mix_dat |= 1; - if ((svga->bpp == 15) || (svga->bpp == 16)) + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; @@ -3621,15 +3697,17 @@ bitblt: } } } else { - if ((svga->bpp == 24) && dev->local && (dev->accel.cmd == 0xc2b5)) { + 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; + 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)) { + 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); @@ -3648,8 +3726,10 @@ bitblt: 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); @@ -3674,7 +3754,7 @@ bitblt: 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); } } @@ -3690,7 +3770,6 @@ bitblt: 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) { if (dev->accel.sx > 0) { WRITE(dev->accel.dest + dev->accel.dx, dest_dat); @@ -3713,15 +3792,18 @@ bitblt: 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++; @@ -3735,9 +3817,8 @@ bitblt: dev->accel.src = dev->accel.cy * dev->pitch; dev->accel.sy--; - if (dev->accel.sy < 0) { + if (dev->accel.sy < 0) return; - } } } } @@ -3750,10 +3831,12 @@ bitblt: } } -static void +#undef CLAMP + +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; @@ -3770,16 +3853,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; @@ -3788,6 +3871,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) { @@ -3818,14 +4109,26 @@ 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) { + ibm8514_t *dev = (ibm8514_t *) priv; uint32_t x; int wx; int wy; 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->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; + } + timer_advance_u64(&svga->timer, svga->dispofftime); + svga->cgastat |= 1; dev->linepos = 1; if (dev->dispon) { @@ -3835,16 +4138,27 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) if (dev->firstline == 2000) { dev->firstline = dev->displine; - video_wait_for_buffer(); + video_wait_for_buffer_monitor(svga->monitor_index); } - svga->render(svga); + 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; } @@ -3852,16 +4166,21 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->displine++; 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->timer, svga->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->sc = 0; dev->maback += (dev->rowoffset << 3); if (dev->interlace) dev->maback += (dev->rowoffset << 3); @@ -3869,13 +4188,13 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->ma = dev->maback; } else { dev->sc++; - dev->sc &= 31; + dev->sc &= 0x1f; dev->ma = dev->maback; } } dev->vc++; - dev->vc &= 2047; + dev->vc &= 0x7ff; if (dev->vc == dev->dispend) { dev->dispon = 0; @@ -3890,6 +4209,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) } if (dev->vc == dev->v_syncstart) { dev->dispon = 0; + svga->cgastat |= 8; x = dev->h_disp; if (dev->interlace && !dev->oddeven) @@ -3910,7 +4230,8 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->oddeven ^= 1; - changeframecount = dev->interlace ? 3 : 2; + svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; + svga->vslines = 0; if (dev->interlace && dev->oddeven) dev->ma = dev->maback = (dev->rowoffset << 1); @@ -3927,6 +4248,9 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; svga->x_add = (overscan_x >> 1); + + dev->hwcursor_on = 0; + dev->hwcursor_latch = dev->hwcursor; } } } @@ -3934,30 +4258,28 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) void ibm8514_recalctimings(svga_t *svga) { - ibm8514_t *dev = &svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - if (ibm8514_on) { - dev->h_disp = (dev->hdisp + 1) << 3; - dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640; - 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->on[0]) { + dev->h_disp = (dev->hdisp + 1) << 3; + dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640; + 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; + dev->dispend += 2; if (dev->dispend == 598) - dev->dispend = 600; + dev->dispend += 2; if (dev->accel.advfunc_cntl & 4) { - if (!vga_on && dev->ibm_mode) { - if (dev->h_disp == 8) { - dev->h_disp = 1024; - dev->dispend = 768; - dev->v_total = 1536; - dev->v_syncstart = 1536; - } + if (dev->h_disp == 8) { + dev->h_disp = 1024; + dev->dispend = 768; + dev->v_total = 1536; + dev->v_syncstart = 1536; } if (dev->dispend == 598) @@ -3972,20 +4294,14 @@ ibm8514_recalctimings(svga_t *svga) dev->v_total >>= 1; } - if (ibm8514_has_vga) { - dev->pitch = dev->ext_pitch; - dev->rowoffset = dev->ext_crt_pitch; - } else - dev->rowoffset = 128; + dev->rowoffset = 0x80; ibm8514_log("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) { - if (dev->h_disp == 1024) { - dev->h_disp = 640; - dev->dispend = 480; - } + if (dev->h_disp == 1024) { + dev->h_disp = 640; + dev->dispend = 480; } if (dev->interlace) { @@ -3997,16 +4313,12 @@ ibm8514_recalctimings(svga_t *svga) dev->v_total >>= 1; } - if (ibm8514_has_vga) { - dev->pitch = dev->ext_pitch; - dev->rowoffset = dev->ext_crt_pitch; - } else - dev->rowoffset = 128; + dev->rowoffset = 0x80; svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } - svga->render = ibm8514_render_8bpp; - ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, mode = %d, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->ibm_mode, dev->accel.advfunc_cntl & 4, ibm8514_has_vga); + svga->render8514 = ibm8514_render_8bpp; + ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, mode = %d, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->ibm_mode, dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled); } 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); } @@ -4014,8 +4326,8 @@ ibm8514_recalctimings(svga_t *svga) 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]); } @@ -4024,7 +4336,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) @@ -4037,35 +4349,36 @@ 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) +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; 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->ibm_mode = 1; - dev->bpp = 8; + dev->type = info->flags; + dev->bpp = 0; 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); @@ -4078,11 +4391,13 @@ static void ibm8514_close(void *priv) { svga_t *svga = (svga_t *) priv; - ibm8514_t *dev = &svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; if (dev) { free(dev->vram); free(dev->changedvram); + + free(dev); } } @@ -4135,7 +4450,7 @@ const device_t ibm8514_mca_device = { void ibm8514_device_add(void) { - if (!ibm8514_enabled || (ibm8514_enabled && ibm8514_has_vga)) + 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 3e0af9620..b54f6b89e 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,6 +57,8 @@ 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 }; @@ -76,19 +78,20 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv) 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); @@ -171,22 +174,74 @@ ati18800_in(uint16_t addr, void *priv) static void ati18800_recalctimings(svga_t *svga) { - ati18800_t *ati18800 = (ati18800_t *) svga->priv; + const ati18800_t *ati18800 = (ati18800_t *) svga->priv; + int clock_sel; - if (svga->crtc[0x17] & 4) { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; + clock_sel = ((svga->miscout >> 2) & 3) | ((ati18800->regs[0xbe] & 0x10) >> 1) | ((ati18800->regs[0xb9] & 2) << 1); + + if (ati18800->regs[0xb6] & 0x10) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->rowoffset <<= 1; + svga->gdcreg[5] &= ~0x40; } - if (!svga->scrblank && ((ati18800->regs[0xb0] & 0x02) || (ati18800->regs[0xb0] & 0x04))) /*Extended 256 colour modes*/ - { - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - svga->rowoffset <<= 1; - svga->ma <<= 1; + 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; + } + } } } @@ -198,6 +253,8 @@ ati18800_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800); + ati18800->type = info->local; + switch (info->local) { default: #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) @@ -207,30 +264,27 @@ ati18800_init(const device_t *info) #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); @@ -300,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, @@ -314,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 72a650184..09d6279f4 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -357,10 +357,10 @@ ati28800_in(uint16_t addr, void *priv) static uint8_t ati28800k_in(uint16_t addr, void *priv) { - ati28800_t *ati28800 = (ati28800_t *) priv; - 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); @@ -400,7 +400,10 @@ ati28800k_in(uint16_t addr, void *priv) static void ati28800_recalctimings(svga_t *svga) { - ati28800_t *ati28800 = (ati28800_t *) svga->priv; + ati28800_t *ati28800 = (ati28800_t *) svga->priv; + int clock_sel; + + 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; @@ -408,66 +411,13 @@ 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; @@ -476,10 +426,24 @@ ati28800_recalctimings(svga_t *svga) if (ati28800->regs[0xb0] & 0x20) { svga->gdcreg[5] |= 0x40; - } + if ((ati28800->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((ati28800->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); + 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)*/ @@ -502,8 +466,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: @@ -516,7 +482,6 @@ ati28800_recalctimings(svga_t *svga) svga->ma_latch <<= 1; } break; - default: break; } @@ -532,7 +497,7 @@ ati28800_recalctimings(svga_t *svga) static void ati28800k_recalctimings(svga_t *svga) { - ati28800_t *ati28800 = (ati28800_t *) svga->priv; + const ati28800_t *ati28800 = (ati28800_t *) svga->priv; ati28800_recalctimings(svga); @@ -586,6 +551,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); @@ -652,6 +619,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, diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index 5a8de5455..7cdd18019 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -46,6 +46,7 @@ #include <86box/mem.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> @@ -65,22 +66,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; @@ -168,23 +170,24 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) } 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: @@ -207,9 +210,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; @@ -237,17 +240,17 @@ ati68860_ramdac_init(UNUSED(const device_t *info)) } 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; } @@ -255,11 +258,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 000000000..447a8eca8 --- /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 a3479c20a..054d83d36 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -26,6 +26,7 @@ #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) @@ -34,7 +35,7 @@ ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) int size; eeprom->type = type; strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); - fp = nvr_fopen(eeprom->fn, "rb"); + fp = nvr_fopen(eeprom->fn, "rb"); size = eeprom->type ? 512 : 128; if (!fp) { memset(eeprom->data, 0xff, size); @@ -52,7 +53,7 @@ ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn) int size; eeprom->type = 0; strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); - fp = nvr_fopen(eeprom->fn, "rb"); + 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.*/ @@ -93,9 +94,7 @@ ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) if (!dat) break; eeprom->state = EEPROM_OPCODE; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case EEPROM_OPCODE: eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0); eeprom->count--; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index d5e721aef..da1b5d556 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -91,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]; @@ -226,6 +229,7 @@ typedef struct mach64_t { int dst_size; int src_size; int host_size; + int temp_cnt; uint32_t dp_bkgd_clr; uint32_t dp_frgd_clr; @@ -417,7 +421,7 @@ mach64_out(uint16_t addr, uint8_t val, void *priv) 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; @@ -436,12 +440,12 @@ mach64_out(uint16_t addr, uint8_t val, void *priv) 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; @@ -451,7 +455,7 @@ mach64_out(uint16_t addr, uint8_t val, void *priv) 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); } } @@ -484,13 +488,13 @@ mach64_in(uint16_t addr, void *priv) 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]; @@ -503,7 +507,7 @@ mach64_in(uint16_t addr, void *priv) void mach64_recalctimings(svga_t *svga) { - mach64_t *mach64 = (mach64_t *) svga->priv; + 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; @@ -620,27 +624,16 @@ mach64_updatemapping(mach64_t *mach64) /*8 MB aperture*/ mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - } else if ((mach64->config_cntl & 3) == 1) { + } else { /*4 MB aperture*/ mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); - } else { - /*Disable aperture on reserved values*/ - mem_mapping_disable(&mach64->linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping); } } else { - if ((mach64->config_cntl & 3) == 2) { - /*2*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); - } else { - /*Disable aperture on reserved values*/ - mem_mapping_disable(&mach64->linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping_2); - } + /*2*8 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); } } else { mem_mapping_disable(&mach64->linear_mapping); @@ -657,11 +650,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) { @@ -676,9 +670,10 @@ mach64_wait_fifo_idle(mach64_t *mach64) thread_wait_event(mach64->fifo_not_full_event, 1); } } +#endif #define READ8(addr, var) \ - switch ((addr) & 3) { \ + switch ((addr) &3) { \ case 0: \ ret = (var) &0xff; \ break; \ @@ -694,7 +689,7 @@ mach64_wait_fifo_idle(mach64_t *mach64) } #define WRITE8(addr, var, val) \ - switch ((addr) & 3) { \ + switch ((addr) &3) { \ case 0: \ var = (var & 0xffffff00) | (val); \ break; \ @@ -748,9 +743,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); -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x113: if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || (addr & 0x3ff) == 0x113) && !(val & 0x80)) { mach64_start_fill(mach64); @@ -973,9 +966,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) case 0x2a4: case 0x2a5: addr += 2; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x2aa: case 0x2ab: WRITE8(addr, mach64->sc_left_right, val); @@ -990,9 +981,7 @@ mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) case 0x2b0: case 0x2b1: addr += 2; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 0x2b6: case 0x2b7: WRITE8(addr, mach64->sc_top_bottom, val); @@ -1181,6 +1170,7 @@ mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val) } } +#if 0 static void fifo_thread(void *param) { @@ -1206,6 +1196,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++; @@ -1241,12 +1234,13 @@ 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; if ((mach64->dst_y_x >> 16) & 0x1000) @@ -1263,11 +1257,11 @@ 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; if ((mach64->src_y_x >> 16) & 0x1000) @@ -1333,10 +1327,12 @@ mach64_start_fill(mach64_t *mach64) mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - for (uint8_t y = 0; y < 8; y++) { - for (uint8_t x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; + if (mach64->pat_cntl & 1) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1; + } } } @@ -1349,7 +1345,9 @@ mach64_start_fill(mach64_t *mach64) mach64->accel.pattern_clr4x2[1][1] = ((mach64->pat_reg1 >> 8) & 0xff); mach64->accel.pattern_clr4x2[1][2] = ((mach64->pat_reg1 >> 16) & 0xff); mach64->accel.pattern_clr4x2[1][3] = ((mach64->pat_reg1 >> 24) & 0xff); - } else if (mach64->pat_cntl & 4) { + } + + if (mach64->pat_cntl & 4) { mach64->accel.pattern_clr8x1[0] = (mach64->pat_reg0 & 0xff); mach64->accel.pattern_clr8x1[1] = ((mach64->pat_reg0 >> 8) & 0xff); mach64->accel.pattern_clr8x1[2] = ((mach64->pat_reg0 >> 16) & 0xff); @@ -1432,10 +1430,12 @@ mach64_start_line(mach64_t *mach64) mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - for (uint8_t y = 0; y < 8; y++) { - for (uint8_t x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; + if (mach64->pat_cntl & 1) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1; + } } } @@ -1535,13 +1535,13 @@ mach64_start_line(mach64_t *mach64) #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) \ @@ -1554,7 +1554,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 @@ -1562,6 +1562,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) { svga_t *svga = &mach64->svga; int cmp_clr = 0; + int mix = 0; if (!mach64->accel.busy) { mach64_log("mach64_blit : return as not busy\n"); @@ -1571,12 +1572,11 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) switch (mach64->accel.op) { case OP_RECT: while (count) { - uint8_t write_mask = 0; - 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; int dst_y; int src_x; @@ -1624,7 +1624,11 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } break; case MONO_SRC_PAT: - mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + if (mach64->dst_cntl & DST_24_ROT_EN) { + if (!mach64->accel.xx_count) + mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + } else + mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; break; case MONO_SRC_1: mix = 1; @@ -1650,18 +1654,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size); break; case SRC_FG: - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if (mach64->dst_cntl & DST_24_ROT_EN) { if (mach64->accel.xinc == -1) { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) src_dat = mach64->accel.dp_frgd_clr & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; else src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; } else { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; else src_dat = mach64->accel.dp_frgd_clr & 0xff; @@ -1670,18 +1674,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) src_dat = mach64->accel.dp_frgd_clr; break; case SRC_BG: - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if (mach64->dst_cntl & DST_24_ROT_EN) { if (mach64->accel.xinc == -1) { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) src_dat = mach64->accel.dp_bkgd_clr & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; else src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; } else { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; else src_dat = mach64->accel.dp_bkgd_clr & 0xff; @@ -1697,6 +1701,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; @@ -1710,7 +1715,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*/ @@ -1730,27 +1735,25 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (!cmp_clr) { old_dest_dat = dest_dat; MIX - - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if (mach64->dst_cntl & DST_24_ROT_EN) { if (mach64->accel.xinc == -1) { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) write_mask = mach64->accel.write_mask & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) write_mask = (mach64->accel.write_mask >> 8) & 0xff; else write_mask = (mach64->accel.write_mask >> 16) & 0xff; } else { - if ((mach64->accel.xx_count % 3) == 2) + if (mach64->accel.xx_count == 2) write_mask = (mach64->accel.write_mask >> 16) & 0xff; - else if ((mach64->accel.xx_count % 3) == 1) + else if (mach64->accel.xx_count == 1) write_mask = (mach64->accel.write_mask >> 8) & 0xff; else write_mask = mach64->accel.write_mask & 0xff; } dest_dat = (dest_dat & write_mask) | (old_dest_dat & ~write_mask); - } else { + } else dest_dat = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask); - } } WRITE(mach64->accel.dst_offset + ((dst_y) * mach64->accel.dst_pitch) + (dst_x), mach64->accel.dst_size); @@ -1773,12 +1776,12 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } } - mach64->accel.xx_count++; mach64->accel.x_count--; + mach64->accel.xx_count = (mach64->accel.xx_count + 1) % 3; if (mach64->accel.x_count <= 0) { + mach64->accel.x_count = mach64->accel.dst_width; mach64->accel.xx_count = 0; - mach64->accel.x_count = mach64->accel.dst_width; - mach64->accel.dst_x = 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; @@ -1800,9 +1803,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } mach64->accel.poly_draw = 0; - mach64->accel.dst_height--; - if (mach64->accel.dst_height <= 0) { /*Blit finished*/ mach64_log("mach64 blit finished\n"); @@ -1830,7 +1831,7 @@ 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; @@ -1965,7 +1966,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; @@ -2527,32 +2528,32 @@ mach64_ext_readb(uint32_t addr, void *priv) 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: @@ -2561,7 +2562,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x11b: case 0x11e: case 0x11f: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_height_width); break; @@ -2569,28 +2570,28 @@ mach64_ext_readb(uint32_t addr, void *priv) 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; @@ -2598,7 +2599,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x131: case 0x132: case 0x133: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_cntl); break; @@ -2606,75 +2607,75 @@ mach64_ext_readb(uint32_t addr, void *priv) 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; @@ -2682,7 +2683,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x1b5: case 0x1b6: case 0x1b7: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_cntl); break; @@ -2690,7 +2691,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x241: case 0x242: case 0x243: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->host_cntl); break; @@ -2698,14 +2699,14 @@ mach64_ext_readb(uint32_t addr, void *priv) 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; @@ -2713,7 +2714,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x289: case 0x28a: case 0x28b: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_cntl); break; @@ -2721,16 +2722,16 @@ mach64_ext_readb(uint32_t addr, void *priv) 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; @@ -2738,16 +2739,16 @@ mach64_ext_readb(uint32_t addr, void *priv) 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; @@ -2755,14 +2756,14 @@ mach64_ext_readb(uint32_t addr, void *priv) 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; @@ -2770,7 +2771,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x2c9: case 0x2ca: case 0x2cb: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->write_mask); break; @@ -2778,7 +2779,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x2cd: case 0x2ce: case 0x2cf: - mach64_wait_fifo_idle(mach64); + //mach64_wait_fifo_idle(mach64); READ8(addr, mach64->chain_mask); break; @@ -2786,21 +2787,21 @@ mach64_ext_readb(uint32_t addr, void *priv) 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; @@ -2808,64 +2809,53 @@ mach64_ext_readb(uint32_t addr, void *priv) 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 (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { - ret = 0; - } else { - if (!FIFO_EMPTY) - wake_fifo_thread(mach64); - ret = 0; - if (FIFO_FULL) - ret = 0xff; - } + ret = 0; 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: - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) - ret = 0; - else - ret = FIFO_EMPTY ? 0 : 1; + ret = 0; break; default: @@ -2879,8 +2869,9 @@ mach64_ext_readb(uint32_t addr, void *priv) uint16_t mach64_ext_readw(uint32_t addr, void *priv) { - mach64_t *mach64 = (mach64_t *) priv; + const mach64_t *mach64 = (mach64_t *) priv; uint16_t ret; + if (!(addr & 0x400)) { mach64_log("nmach64_ext_readw: addr=%04x\n", addr); ret = 0xffff; @@ -2907,8 +2898,9 @@ mach64_ext_readw(uint32_t addr, void *priv) uint32_t mach64_ext_readl(uint32_t addr, void *priv) { - mach64_t *mach64 = (mach64_t *) priv; - 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; @@ -3047,10 +3039,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); } else if (addr & 0x300) { - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) - mach64_accel_write_fifo(mach64, addr & 0x3ff, val); - else - mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); + mach64_accel_write_fifo(mach64, addr & 0x3ff, val); } else switch (addr & 0x3ff) { case 0x00: @@ -3059,6 +3048,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) case 0x03: WRITE8(addr, mach64->crtc_h_total_disp, val); svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; break; case 0x08: case 0x09: @@ -3066,6 +3056,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) 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: @@ -3073,6 +3064,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) case 0x0f: WRITE8(addr, mach64->crtc_v_sync_strt_wid, val); svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; break; case 0x14: @@ -3081,7 +3073,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) 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: @@ -3102,6 +3094,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) svga->fb_only = 0; svga->dpms = !!(mach64->crtc_gen_cntl & 0x0c); svga_recalctimings(&mach64->svga); + svga->fullchange = svga->monitor->mon_changeframecount; break; case 0x40: @@ -3276,10 +3269,7 @@ mach64_ext_writew(uint32_t addr, uint16_t val, void *priv) mach64_ext_writeb(addr, val, priv); mach64_ext_writeb(addr + 1, val >> 8, priv); } else if (addr & 0x300) { - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) - mach64_accel_write_fifo_w(mach64, addr & 0x3fe, val); - else - mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); + mach64_accel_write_fifo_w(mach64, addr & 0x3fe, val); } else switch (addr & 0x3fe) { default: @@ -3300,10 +3290,7 @@ mach64_ext_writel(uint32_t addr, uint32_t val, void *priv) mach64_ext_writew(addr, val, priv); mach64_ext_writew(addr + 2, val >> 16, priv); } else if (addr & 0x300) { - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) - mach64_accel_write_fifo_l(mach64, addr & 0x3fc, val); - else - mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); + mach64_accel_write_fifo_l(mach64, addr & 0x3fc, val); } else switch (addr & 0x3fc) { default: @@ -3317,7 +3304,7 @@ uint8_t mach64_ext_inb(uint16_t port, void *priv) { mach64_t *mach64 = (mach64_t *) priv; - uint8_t ret = 0xff; + uint8_t ret = 0xff; switch (port) { case 0x02ec: @@ -3716,6 +3703,9 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv) WRITE8(port, mach64->config_cntl, val); mach64_updatemapping(mach64); break; + + default: + break; } } void @@ -4036,9 +4026,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) { @@ -4216,7 +4206,7 @@ mach64_io_set(mach64_t *mach64) uint8_t mach64_pci_read(UNUSED(int func), int addr, void *priv) { - mach64_t *mach64 = (mach64_t *) priv; + const mach64_t *mach64 = (mach64_t *) priv; switch (addr) { case 0x00: @@ -4387,20 +4377,23 @@ mach64_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) 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); @@ -4409,28 +4402,23 @@ 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); + 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; } @@ -4448,7 +4436,7 @@ 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->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*/ @@ -4526,12 +4514,6 @@ mach64_close(void *priv) { mach64_t *mach64 = (mach64_t *) priv; - 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); - svga_close(&mach64->svga); ddc_close(mach64->ddc); @@ -4553,7 +4535,7 @@ mach64_force_redraw(void *priv) { 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 index 797ae3f19..21f6abd29 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -36,66 +36,91 @@ #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> -#define BIOS_MACH8_ROM_PATH "roms/video/mach8/BIOS.BIN" -#define BIOS_MACH32_ISA_ROM_PATH "roms/video/mach32/MACH32ISA.VBI" -#define BIOS_MACH32_VLB_ROM_PATH "roms/video/mach32/MACH32VLB.VBI" -#define BIOS_MACH32_PCI_ROM_PATH "roms/video/mach32/MACH32PCI.BIN" +#define BIOS_MACH8_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" typedef struct mach_t { ati_eeprom_t eeprom; svga_t svga; - rom_t bios_rom; + 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; - int card; - int index; + 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 cursor_col_0, cursor_col_1; - uint8_t ext_cur_col_0_r, ext_cur_col_1_r; - uint8_t ext_cur_col_0_g, ext_cur_col_1_g; - uint16_t cursor_offset_lo, cursor_offset_hi; - uint16_t cursor_x, cursor_y; + 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, bank_r; + uint8_t ap_size; + uint8_t bank_w; + uint8_t bank_r; + uint16_t shadow_set; + int ext_on[2]; 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; + 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, src_y; - int16_t bres_count; + uint16_t src_x; + uint16_t src_y; + int16_t bres_count; uint16_t clock_sel; - uint16_t crt_offset_lo; - uint16_t crt_offset_hi; + uint16_t crt_pitch; + uint16_t ge_pitch; uint16_t dest_cmp_fn; uint16_t dp_config; uint16_t ext_ge_config; @@ -103,54 +128,76 @@ typedef struct mach_t { uint16_t ge_offset_hi; uint16_t linedraw_opt; uint16_t max_waitstates; - uint8_t patt_data_idx; - uint8_t patt_data[0x18]; + 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; - uint8_t test2[2], test3[2]; - int src_y_dir; - int cmd_type; - int block_write_mono_pattern_enable; - int mono_pattern_enable; - int16_t cx_end_line, cy_end_line; - int16_t cx, cx_end, cy_end, dx, dx_end, dy_end; - int16_t dx_start, dy_start; - int16_t cy, sx_start, sx_end; - int16_t sx, x_count, xx_count, xxx_count; - int16_t sy, y_count; - int16_t err; - int16_t width, src_width; - int16_t height; - int poly_src, temp_cnt; - int stepx, stepy, src_stepx; - uint8_t color_pattern[16]; - uint8_t color_pattern_full[32]; + uint16_t test2; + uint16_t test3; + uint16_t test4; + 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]; + int mono_pattern[8][8]; uint32_t ge_offset; uint32_t crt_offset; uint32_t patt_len_reg; - int poly_fill; + int poly_fill; uint16_t dst_clr_cmp_mask; - int clip_overrun; - int color_pattern_idx; + int clip_overrun; + int color_pattern_idx; } accel; - atomic_int force_busy, force_busy2; + atomic_int force_busy; } mach_t; 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_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; - +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); static void mach32_updatemapping(mach_t *mach); @@ -172,64 +219,67 @@ mach_log(const char *fmt, ...) # define mach_log(fmt, ...) #endif -#define READ_PIXTRANS_BYTE_IO(cx, n, vgacore) \ - if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ - if (vgacore) { \ - if ((svga->bpp == 15) || (svga->bpp == 16)) \ - if (n == 0) \ - mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (svga->vram_mask >> 1)] & 0xff; \ - else \ - mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (svga->vram_mask >> 1)] >> 8; \ - else \ - mach->accel.pix_trans[(n)] = svga->vram[(dev->accel.dest + (cx) + (n)) & svga->vram_mask]; \ - } else \ - mach->accel.pix_trans[(n)] = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ +#define WRITE8(addr, var, val) \ + switch ((addr) & 1) { \ + case 0: \ + var = (var & 0xff00) | (val); \ + break; \ + case 1: \ + var = (var & 0x00ff) | ((val) << 8); \ + break; \ } -#define READ_PIXTRANS_WORD(cx, n, vgacore) \ +#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 (vgacore) { \ - if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (svga->vram_mask >> 1)]; \ - } else { \ - temp = svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } \ + 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 ((svga->bpp == 8) || (svga->bpp == 24)) { \ - if (vgacore) { \ - temp = svga->vram[((dev->accel.dest) + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[((dev->accel.dest) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } 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 ((svga->bpp == 15) || (svga->bpp == 16)) { \ - temp = vram_w[((dev->accel.dest) + (cx) + (n)) & (svga->vram_mask >> 1)]; \ + 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 ((svga->bpp == 8) || (svga->bpp == 24)) { \ - if (vgacore) { \ - temp = svga->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & svga->vram_mask]; \ - temp |= (svga->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ - } 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); \ - } \ - } else if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - temp = vram_w[((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & (svga->vram_mask >> 1)]; \ + 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, vgacore) \ - if ((svga->bpp == 8) || (svga->bpp == 24)) \ - dat = vgacore ? (svga->vram[(addr) & (svga->vram_mask)]) : (dev->vram[(addr) & (dev->vram_mask)]); \ - else if ((svga->bpp == 15) || (svga->bpp == 16)) \ - dat = vram_w[(addr) & (svga->vram_mask >> 1)]; +#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) \ { \ @@ -334,21 +384,15 @@ mach_log(const char *fmt, ...) } -#define WRITE(addr, dat, vgacore) \ - if ((svga->bpp == 8) || (svga->bpp == 24)) { \ - if (vgacore) { \ - svga->vram[((addr)) & (svga->vram_mask)] = dat; \ - svga->changedvram[(((addr)) & (svga->vram_mask)) >> 12] = changeframecount; \ - } else { \ - dev->vram[((addr)) & (dev->vram_mask)] = dat; \ - dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ - } \ - } else if ((svga->bpp == 15) || (svga->bpp == 16)) { \ - vram_w[((addr)) & (svga->vram_mask >> 1)] = dat; \ - svga->changedvram[(((addr)) & (svga->vram_mask >> 1)) >> 11] = changeframecount; \ +#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) { @@ -368,62 +412,60 @@ mach_pixel_read(mach_t *mach) } 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, UNUSED(int len)) +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) { - svga_t *svga = &mach->svga; - int compare_mode; - int 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 *) svga->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; + 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 ((svga->bpp == 8) || (svga->bpp == 24)) { + 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; + 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; - mach->force_busy2 = 1; - dev->force_busy = 1; - dev->force_busy2 = 1; + mach->force_busy = 1; + dev->force_busy = 1; + dev->force_busy2 = 1; } if (cpu_input) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { + if (dev->bpp) { if ((mach->accel.dp_config & 0x200) && (count == 2)) { count >>= 1; } } } - if ((svga->bpp == 8) || (svga->bpp == 15) || (svga->bpp == 16) || (svga->bpp == 24)) { - if (svga->bpp == 24) + if ((dev->accel_bpp == 8) || (dev->accel_bpp == 15) || (dev->accel_bpp == 16) || (dev->accel_bpp == 24)) { + if (dev->accel_bpp == 24) mach_log("24BPP: CMDType=%d, cwh(%d,%d,%d,%d), dpconfig=%04x\n", cmd_type, clip_l, clip_r, clip_t, clip_b, mach->accel.dp_config); else - mach_log("BPP=%d, CMDType = %d, offs=%08x, DPCONFIG = %04x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, dstx = %d, dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", svga->bpp, cmd_type, mach->accel.ge_offset, mach->accel.dp_config, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); + mach_log("RdMask=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, DPCONFIG = %04x, 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, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, mach->accel.dp_config, 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) { @@ -443,8 +485,8 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.desty_axstp >= 0x600) dev->accel.cy |= ~0x5ff; - mach->accel.width = mach->accel.bres_count; - dev->accel.sx = 0; + 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); @@ -456,11 +498,11 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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_available = 0; dev->data_available2 = 0; return; } else if (mach_pixel_read(mach)) { - dev->data_available = 1; + dev->data_available = 1; dev->data_available2 = 1; return; } @@ -478,8 +520,8 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (mono_src == 1) { - count = mach->accel.width; - mix_dat = mach->accel.patt_data[0x10]; + count = mach->accel.width; + mix_dat = mach->accel.patt_data[0x10]; dev->accel.temp_cnt = 8; } @@ -490,7 +532,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix = 1; break; case 1: - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat >>= 8; } @@ -515,10 +557,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } break; case 3: - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + 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, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); } mix = (mix & rd_mask) == rd_mask; break; @@ -528,109 +570,109 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { - if (mach->accel.linedraw_opt & 0x02) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); - } - 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)) { - 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 ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); - } - 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 ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); - } - } - - switch (compare_mode) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; case 1: - compare = 1; + src_dat = dev->accel.frgd_color; break; case 2: - compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + src_dat = cpu_dat; break; case 3: - compare = (dest_dat < dest_cmp_clr) ? 0 : 1; - break; - case 4: - compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + 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: - 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; + 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 (!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 & 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.dp_config & 0x10) { - if (mach->accel.linedraw_opt & 0x04) { - if (dev->accel.sx < mach->accel.width) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); - } - } + 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 { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + 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 { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + 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); + } } } } @@ -641,10 +683,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; switch (mach->accel.linedraw_opt & 0xe0) { case 0x00: @@ -701,7 +743,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix = 1; break; case 1: - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat >>= 8; } @@ -726,10 +768,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } break; case 3: - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + 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, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix); } mix = (mix & rd_mask) == rd_mask; break; @@ -739,109 +781,109 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { - if (mach->accel.linedraw_opt & 0x02) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); - } - 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)) { - 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 ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); - } - 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 ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); - } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); - } - } - - switch (compare_mode) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; case 1: - compare = 1; + src_dat = dev->accel.frgd_color; break; case 2: - compare = (dest_dat >= dest_cmp_clr) ? 0 : 1; + src_dat = cpu_dat; break; case 3: - compare = (dest_dat < dest_cmp_clr) ? 0 : 1; - break; - case 4: - compare = (dest_dat != dest_cmp_clr) ? 0 : 1; + 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: - 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; + 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 (!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 & 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.dp_config & 0x10) { - if (mach->accel.linedraw_opt & 0x04) { - if (dev->accel.sx < mach->accel.width) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); - } - } + 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 { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + 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 { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + 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); + } } } } @@ -852,10 +894,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.linedraw_opt & 0x40) { dev->accel.dy += mach->accel.stepy; @@ -888,6 +930,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.sx++; } } + mach->accel.poly_fill = 0; dev->accel.cur_x = dev->accel.dx; dev->accel.cur_y = dev->accel.dy; break; @@ -932,13 +975,13 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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; + 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 ((svga->bpp == 24) && (mono_src != 1)) { + 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 ((svga->bpp == 24) && (frgd_sel == 5) && (mono_src == 1) && (mach->accel.patt_len_reg & 0x4000)) + } 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*/ @@ -951,17 +994,17 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.dy_end > mach->accel.dy_start) { mach->accel.height = (mach->accel.dy_end - mach->accel.dy_start); - mach->accel.stepy = 1; + 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; + mach->accel.stepy = -1; } else { mach->accel.height = 0; - mach->accel.stepy = 1; + mach->accel.stepy = 1; } dev->accel.sy = 0; - if ((svga->bpp == 15) || (svga->bpp == 16)) + 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)); @@ -1001,15 +1044,15 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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 ((svga->bpp == 15) || (svga->bpp == 16)) + 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 ((svga->bpp == 24) && (frgd_sel == 5)) { + 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 - mach_log("BitBLT=%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 << 2)); + 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)) { @@ -1024,7 +1067,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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; + uint32_t temp = (y & 4) ? mono_dat1 : mono_dat0; mach->accel.mono_pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1; } } @@ -1033,11 +1076,11 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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_available = 0; dev->data_available2 = 0; return; } else if (mach_pixel_read(mach)) { - dev->data_available = 1; + dev->data_available = 1; dev->data_available2 = 1; return; } @@ -1046,20 +1089,20 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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); + 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 ((svga->bpp == 15) || (svga->bpp == 16)) { + 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 ((svga->bpp == 24) && (mach->accel.patt_len < 3)) { + 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); @@ -1101,10 +1144,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix = 1; break; case 1: - if (mach->accel.mono_pattern_enable) { + if (mach->accel.mono_pattern_enable) mix = mach->accel.mono_pattern[dev->accel.dy & 7][dev->accel.dx & 7]; - } else { - if ((svga->bpp == 24) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) + else { + if ((dev->accel_bpp == 24) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) mix = 1; else { if (!dev->accel.temp_cnt) { @@ -1134,7 +1177,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } break; case 3: - READ(dev->accel.src + ((dev->accel.cx)), mix, dev->local); + READ(dev->accel.src + dev->accel.cx, mix); mix = (mix & rd_mask) == rd_mask; break; @@ -1142,16 +1185,15 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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) { - READ(dev->accel.src + (dev->accel.cx), poly_src, dev->local); + 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 = !mach->accel.poly_fill; + mach->accel.poly_fill ^= 1; } - if (!mach->accel.poly_fill || !(mach->accel.dp_config & 0x02)) { + 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; @@ -1166,19 +1208,17 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach_pixel_read(mach)) src_dat = cpu_dat; else { - READ(dev->accel.src + (dev->accel.cx), src_dat, dev->local); - if (mono_src == 3) { + 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 ((svga->bpp == 15) || (svga->bpp == 16)) { + if (dev->bpp) src_dat = mach->accel.color_pattern_word[mach->accel.color_pattern_idx]; - } else { + else src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; - } } else src_dat = 0; break; @@ -1186,72 +1226,72 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 default: break; } - } - if ((svga->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, dev->local); - } else { - READ(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); - } - } else { - READ(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); - } - - 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 ((svga->bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + 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, dev->local); + READ(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); } else { - WRITE(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + READ(dev->accel.dest + dev->accel.dx, dest_dat); } } else { - WRITE(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + 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 ((svga->bpp == 8) || (svga->bpp == 24)) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; - if ((mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3)) { + 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) { @@ -1260,8 +1300,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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 ((svga->bpp == 15) || (svga->bpp == 16)) + 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)); @@ -1270,34 +1311,33 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.dx += mach->accel.stepx; - if ((svga->bpp == 8) || ((svga->bpp == 24) && (mach->accel.patt_len >= 3) && (mono_src != 1))) + 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 ((svga->bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mach->accel.patt_len >= 3) && (mono_src != 1)) { + 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 ((svga->bpp == 24) && (mach->accel.patt_len < 3)) { + } 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 { + } else mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; - } - } else if ((svga->bpp == 24) && (mach->accel.patt_len_reg & 0x4000) && (frgd_sel == 5)) { + + } 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 ((svga->bpp == 15) || (svga->bpp == 16)) { + 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) { - mach->accel.poly_fill = 0; - dev->accel.sx = 0; + dev->accel.sx = 0; if (mach->accel.stepx == -1) dev->accel.dx += mach->accel.width; else @@ -1306,17 +1346,18 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.dy += mach->accel.stepy; dev->accel.sy++; - if ((svga->bpp == 15) || (svga->bpp == 16)) + mach->accel.poly_fill = 0; + if (dev->bpp) dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); - else { + else dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); - } - if ((mono_src == 1) && (svga->bpp == 24) && (frgd_sel == 5)) + + 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 ((svga->bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mono_src != 1)) + 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; @@ -1324,9 +1365,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 return; } if (dev->accel.sy >= mach->accel.height) { - if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 2) || (frgd_sel == 3) || (bkgd_sel == 2) || (bkgd_sel == 3)) + 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) && (svga->bpp == 24) && (mach->accel.patt_len_reg & 0x4000)) + 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; @@ -1359,15 +1400,15 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.sx = 0; - mach_log("Linedraw: c(%d,%d), d(%d,%d), cend(%d,%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_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_available = 0; dev->data_available2 = 0; return; } else if (mach_pixel_read(mach)) { - dev->data_available = 1; + dev->data_available = 1; dev->data_available2 = 1; return; } @@ -1381,11 +1422,11 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (mono_src == 1) { - mix_dat = mach->accel.patt_data[0x10]; + 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); + 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) { @@ -1401,7 +1442,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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)) { + 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: @@ -1416,14 +1457,13 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 case 3: if (mach_pixel_read(mach)) src_dat = cpu_dat; - else { + else src_dat = 0; - } break; case 5: - if (mix) { + if (mix) src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; - } else + else src_dat = 0; break; @@ -1431,10 +1471,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { @@ -1471,11 +1511,19 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); } } - if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } else @@ -1484,10 +1532,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (!count) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.err >= 0) { dev->accel.cy += mach->accel.stepy; @@ -1520,11 +1568,17 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; default: - break; + break; } - if (((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b)) { + 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; @@ -1553,10 +1607,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { @@ -1589,7 +1643,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (!compare) { if (mach_pixel_write(mach)) { old_dest_dat = dest_dat; - MIX(mix, dest_dat, src_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); } } @@ -1597,17 +1653,17 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { if (mach->accel.linedraw_opt & 0x04) { if (dev->accel.sx < mach->accel.width) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } else { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } @@ -1617,10 +1673,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.sx >= mach->accel.width) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.err >= 0) { dev->accel.cy += mach->accel.stepy; @@ -1645,7 +1701,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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)) { + 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: @@ -1675,10 +1731,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { case 1: @@ -1716,10 +1772,20 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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 { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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 @@ -1728,10 +1794,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (!count) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.err >= 0) { dev->accel.cx += mach->accel.stepx; @@ -1767,8 +1833,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if (((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b)) { + 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; @@ -1797,10 +1864,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((svga->bpp == 15) || (svga->bpp == 16)) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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, dev->local); + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { @@ -1841,17 +1908,17 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { if (mach->accel.linedraw_opt & 0x04) { if (dev->accel.sx < mach->accel.width) { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } else { - if ((svga->bpp == 15) || (svga->bpp == 16)) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + 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, dev->local); + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } @@ -1861,10 +1928,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.sx >= mach->accel.width) break; - if (svga->bpp == 8) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; if (mach->accel.err >= 0) { dev->accel.cx += mach->accel.stepx; @@ -1877,10 +1944,11 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } } + 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]; + 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)*/ @@ -1917,7 +1985,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } dev->accel.sx = 0; - if ((svga->bpp == 24) && (mach->accel.patt_len < 0x17)) + if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 0x17)) mach->accel.color_pattern_idx = 0; /*Step Y*/ @@ -1936,7 +2004,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.stepy = 0; } - if ((svga->bpp == 15) || (svga->bpp == 16)) + 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)); @@ -1973,12 +2041,12 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } mach->accel.sx = 0; - if ((svga->bpp == 15) || (svga->bpp == 16)) + 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 ((svga->bpp == 24) && (frgd_sel == 5)) { + 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; @@ -1997,11 +2065,11 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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_available = 0; dev->data_available2 = 0; return; } else if (mach_pixel_read(mach)) { - dev->data_available = 1; + dev->data_available = 1; dev->data_available2 = 1; return; } @@ -2009,13 +2077,13 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (mono_src == 1) { - count = mach->accel.width; - mix_dat = mach->accel.patt_data[0x10]; + count = mach->accel.width; + mix_dat = mach->accel.patt_data[0x10]; dev->accel.temp_cnt = 8; } if (frgd_sel == 5) { - if (svga->bpp != 24) { + 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]; } @@ -2040,7 +2108,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix = 1; break; case 1: - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat >>= 8; } @@ -2065,7 +2133,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } break; case 3: - READ(dev->accel.src + (dev->accel.cx), mix, dev->local); + READ(dev->accel.src + (dev->accel.cx), mix); mix = (mix & rd_mask) == rd_mask; break; @@ -2073,8 +2141,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if ((dev->accel.dx) >= clip_l && (dev->accel.dx) <= clip_r && - (dev->accel.dy) >= clip_t && (dev->accel.dy) <= clip_b) { + 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; @@ -2089,7 +2156,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach_pixel_read(mach)) src_dat = cpu_dat; else { - READ(dev->accel.src + (dev->accel.cx), src_dat, dev->local); + READ(dev->accel.src + (dev->accel.cx), src_dat); if (mono_src == 3) { src_dat = (src_dat & rd_mask) == rd_mask; } @@ -2097,7 +2164,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; case 5: if (mix) { - if (svga->bpp == 24) { + if (dev->accel_bpp == 24) { if (mach->accel.patt_len == 0x17) src_dat = mach->accel.color_pattern_full[mach->accel.color_pattern_idx]; else @@ -2112,7 +2179,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - READ(dev->accel.dest + (dev->accel.dx), dest_dat, dev->local); + READ(dev->accel.dest + (dev->accel.dx), dest_dat); switch (compare_mode) { case 1: @@ -2150,14 +2217,14 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (mach->accel.dp_config & 0x10) { - WRITE(dev->accel.dest + (dev->accel.dx), dest_dat, dev->local); + WRITE(dev->accel.dest + (dev->accel.dx), dest_dat); } } - if ((svga->bpp == 8) || (svga->bpp == 24)) - cpu_dat >>= 8; - else + if (dev->bpp) cpu_dat >>= 16; + else + cpu_dat >>= 8; dev->accel.cx += mach->accel.src_stepx; mach->accel.sx++; @@ -2168,14 +2235,14 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } else dev->accel.cx -= mach->accel.src_width; dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1); - if ((svga->bpp == 15) || (svga->bpp == 16)) + 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 ((svga->bpp == 24) && (mach->accel.patt_len == 0x17)) { + 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) @@ -2184,7 +2251,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.color_pattern_idx == 6) mach->accel.color_pattern_idx = 0; } - } else if ((svga->bpp == 24) && (mach->accel.patt_len < 3)) { + } 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; @@ -2195,7 +2262,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.sx >= mach->accel.width) { dev->accel.sx = 0; dev->accel.dy += mach->accel.stepy; - if ((svga->bpp == 15) || (svga->bpp == 16)) + 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)); @@ -2214,7 +2281,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } static void -mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, UNUSED(uint16_t port), uint16_t val, uint16_t len) +mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, uint16_t val) { int frgd_sel; int bkgd_sel; @@ -2232,25 +2299,25 @@ mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, UNUSED(uint16_t port), uin case 0x000: /*8-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { - if ((mach->accel.dp_config & 0x1000) && dev->local) + if ((mach->accel.dp_config & 0x1000) && ((dev->local & 0xff) >= 0x02)) val = (val >> 8) | (val << 8); - mach_accel_start(mach->accel.cmd_type, 1, 8, val | (val << 16), 0, mach, dev, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev); } break; @@ -2262,11 +2329,12 @@ mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, UNUSED(uint16_t port), uin static void mach_out(uint16_t addr, uint8_t val, void *priv) { - mach_t *mach = (mach_t *) priv; - svga_t *svga = &mach->svga; - ibm8514_t *dev = &svga->dev8514; - uint8_t old; - uint8_t rs2; + 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; @@ -2276,7 +2344,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) mach->index = val; break; case 0x1cf: - old = mach->regs[mach->index]; + 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) { @@ -2289,7 +2357,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) svga_recalctimings(svga); break; case 0xad: - if (dev->local) { + if ((dev->local & 0xff) >= 0x02) { if ((old ^ val) & 0x0c) svga_recalctimings(svga); } @@ -2305,22 +2373,22 @@ mach_out(uint16_t addr, uint8_t val, void *priv) 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) { + if ((dev->local & 0xff) >= 0x02) { mach->bank_r |= ((mach->regs[0xae] & 0x0c) << 2); mach->bank_w |= ((mach->regs[0xae] & 3) << 4); } - if (ibm8514_on) + 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) { + if ((dev->local & 0xff) >= 0x02) { mach->bank_w |= ((mach->regs[0xae] & 3) << 4); } mach->bank_r = mach->bank_w; - if (ibm8514_on) + 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->read_bank = mach->bank_r << 16; svga->write_bank = mach->bank_w << 16; if (mach->index == 0xbe) { @@ -2341,7 +2409,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) svga_recalctimings(svga); break; case 0xb8: - if (dev->local) { + if ((dev->local & 0xff) >= 0x02) { if ((old ^ val) & 0x40) svga_recalctimings(svga); } else { @@ -2364,11 +2432,12 @@ mach_out(uint16_t addr, uint8_t val, void *priv) case 0x2ec: case 0x2ed: rs2 = !!(mach->accel.ext_ge_config & 0x1000); - if (dev->local) { - if (mach->pci_bus) - ati68860_ramdac_out((addr & 3) | (rs2 << 2), val, svga->ramdac, svga); + 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 - svga_out(addr, val, svga); + ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else svga_out(addr, val, svga); return; @@ -2377,33 +2446,26 @@ mach_out(uint16_t addr, uint8_t val, void *priv) case 0x3C7: case 0x3C8: case 0x3C9: - rs2 = !!(mach->accel.ext_ge_config & 0x1000); - if (dev->local) { - if (mach->pci_bus) - ati68860_ramdac_out((addr & 3) | (rs2 << 2), val, svga->ramdac, svga); + 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 - svga_out(addr, val, svga); + ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else svga_out(addr, val, svga); return; - case 0x3CF: - if (svga->gdcaddr == 6) { - uint8_t old_val = svga->gdcreg[6]; - svga->gdcreg[6] = val; - if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc)) - mach32_updatemapping(mach); - return; - } - break; - case 0x3D4: svga->crtcreg = val & 0x3f; return; case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + if (svga->crtcreg & 0x20) return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + 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]; @@ -2430,11 +2492,12 @@ mach_out(uint16_t addr, uint8_t val, void *priv) static uint8_t mach_in(uint16_t addr, void *priv) { - mach_t *mach = (mach_t *) priv; - svga_t *svga = &mach->svga; - ibm8514_t *dev = &svga->dev8514; - uint8_t temp; - uint8_t rs2; + 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; @@ -2453,7 +2516,7 @@ mach_in(uint16_t addr, void *priv) break; case 0xb0: temp = mach->regs[0xb0] | 0x80; - if (dev->local) { /*Mach32 VGA 1MB memory*/ + if ((dev->local & 0xff) >= 0x02) { /*Mach32 VGA 1MB memory*/ temp |= 0x08; temp &= ~0x10; } else { /*ATI 28800 VGA 512kB memory*/ @@ -2467,6 +2530,10 @@ mach_in(uint16_t addr, void *priv) temp |= 8; break; + case 0xbd: + temp = mach->regs[0xbd] | 0x10; + break; + default: temp = mach->regs[mach->index]; break; @@ -2478,40 +2545,40 @@ mach_in(uint16_t addr, void *priv) case 0x2ec: case 0x2ed: rs2 = !!(mach->accel.ext_ge_config & 0x1000); - if (dev->local) { - if (mach->pci_bus) - return ati68860_ramdac_in((addr & 3) | (rs2 << 2), svga->ramdac, svga); + 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 - return svga_in(addr, svga); - } - return svga_in(addr, svga); + 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->accel.ext_ge_config & 0x1000); - if (dev->local) { - if (mach->pci_bus) - return ati68860_ramdac_in((addr & 3) | (rs2 << 2), svga->ramdac, svga); + 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 - return svga_in(addr, svga); - } - return svga_in(addr, svga); + 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: - temp = svga->crtc[svga->crtcreg]; - break; - case 0x3DA: - svga->attrff = 0; - if (svga->cgastat & 0x01) - svga->cgastat &= ~0x38; + if (svga->crtcreg & 0x20) + temp = 0xff; else - svga->cgastat ^= 0x38; - return svga->cgastat; + temp = svga->crtc[svga->crtcreg]; + break; default: temp = svga_in(addr, svga); @@ -2523,63 +2590,18 @@ mach_in(uint16_t addr, void *priv) static void mach_recalctimings(svga_t *svga) { - mach_t *mach = (mach_t *) svga->priv; - ibm8514_t *dev = &svga->dev8514; + const mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + int clock_sel; - if (vga_on && !ibm8514_on) { - switch (((mach->regs[0xbe] & 0x10) >> 1) | ((mach->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: - mach_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: - mach_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; + clock_sel = ((svga->miscout >> 2) & 3) | ((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1); - default: - break; - } + 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) @@ -2588,36 +2610,7 @@ mach_recalctimings(svga_t *svga) if (mach->regs[0xb0] & 0x40) svga->ma_latch |= 0x20000; - if (dev->local) { - if (mach->regs[0xad] & 0x04) - svga->ma_latch |= 0x40000; - - if (mach->regs[0xad] & 0x08) - svga->ma_latch |= 0x80000; - - if (mach->regs[0xb8] & 0x40) - svga->clock *= 2; - } else { - switch (mach->regs[0xb8] & 0xc0) { - case 0x40: - svga->clock *= 2; - break; - case 0x80: - svga->clock *= 3; - break; - case 0xc0: - svga->clock *= 4; - break; - - default: - break; - } - } - - if (mach->regs[0xa7] & 0x80) - svga->clock *= 3; - - if (mach->regs[0xb6] & 0x10) { + if ((mach->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; @@ -2626,155 +2619,251 @@ mach_recalctimings(svga_t *svga) 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->ati_4color = 1; + } else + svga->ati_4color = 0; } - if (vga_on && !ibm8514_on) { - 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 - 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) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else { - svga->render = svga_render_8bpp_highres; - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; - } - break; + 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"); + if ((dev->local & 0xff) >= 0x02) { + dev->h_disp = (dev->hdisp + 1) << 3; + dev->h_total = (dev->htotal + 1); + dev->v_total = (dev->vtotal + 1); + dev->v_syncstart = (dev->vsyncstart + 1); + dev->dispend = ((dev->vdisp >> 1) + 1); + dev->rowcount = !!(dev->disp_cntl & 0x08); - default: - break; - } + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->dispend == 598) + dev->dispend += 2; + + if (dev->accel.advfunc_cntl & 4) { + if (mach->shadow_set & 2) { + if ((dev->h_disp == 8) && !dev->bpp) { + dev->h_disp = 1024; + dev->dispend = 768; + dev->v_total = 1536; + dev->v_syncstart = 1536; + } + mach_log("Shadow set 2.\n"); + svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + } else + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + } else { + if ((dev->h_disp == 1024) && !dev->bpp) { + dev->h_disp = 640; + dev->dispend = 480; + } + if (mach->shadow_set & 1) { + mach_log("Shadow set 1.\n"); + svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + } else + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + } + + 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.\n", dev->h_disp, dev->dispend, dev->pitch, dev->ext_crt_pitch, mach->accel.ext_ge_config & 0xcec0, dev->accel_bpp); + 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; } } - } - } else if (dev->local) { - if (ibm8514_on) { - svga->hdisp_time = svga->hdisp = (dev->hdisp + 1) << 3; - dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640; - svga->htotal = (dev->htotal + 1); - svga->vtotal = (dev->vtotal + 1); - svga->vsyncstart = (dev->vsyncstart + 1); - svga->rowcount = !!(dev->disp_cntl & 0x08); - svga->dispend = ((dev->vdisp >> 1) + 1); - svga->interlace = dev->interlace; - svga->split = 0xffffff; - svga->vblankstart = svga->dispend; + switch (mach->regs[0xb8] & 0xc0) { + case 0x40: + svga->clock *= 2; + break; + case 0x80: + svga->clock *= 3; + break; + case 0xc0: + svga->clock *= 4; + break; - if (svga->dispend == 766) { - svga->dispend = 768; - svga->vblankstart = svga->dispend; + default: + break; } + } else { + dev->h_disp = (dev->hdisp + 1) << 3; + 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 (svga->dispend == 598) { - svga->dispend = 600; - svga->vblankstart = svga->dispend; - } + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->dispend == 598) + dev->dispend += 2; if (dev->accel.advfunc_cntl & 4) { - if (dev->ibm_mode) { - if (svga->hdisp == 8) { - svga->hdisp = 1024; - svga->dispend = 768; - svga->vtotal = 1536; - svga->vsyncstart = 1536; + if (mach->shadow_set & 2) { + if (dev->h_disp == 8) { + dev->h_disp = 1024; + dev->dispend = 768; + dev->v_total = 1536; + dev->v_syncstart = 1536; } - } - - if (svga->interlace) { - svga->dispend >>= 1; - svga->vsyncstart >>= 2; - svga->vtotal >>= 2; - } else { - svga->vsyncstart >>= 1; - svga->vtotal >>= 1; - } - - dev->pitch = dev->ext_pitch; - svga->rowoffset = dev->ext_crt_pitch; - - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + } else + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); } else { - if (dev->ibm_mode) { - if ((svga->hdisp == 1024) && !dev->internal_pitch) { - svga->hdisp = 640; - svga->dispend = 480; - } + if (dev->h_disp == 1024) { + dev->h_disp = 640; + dev->dispend = 480; } - - if (svga->interlace) { - svga->dispend >>= 1; - svga->vsyncstart >>= 2; - svga->vtotal >>= 2; - } else { - svga->vsyncstart >>= 1; - svga->vtotal >>= 1; - } - - dev->pitch = dev->ext_pitch; - svga->rowoffset = dev->ext_crt_pitch; - - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + if (mach->shadow_set & 1) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + } else + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); } - switch (svga->bpp) { - default: - 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; + 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.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0); + svga->map8 = dev->pallook; + svga->render8514 = ibm8514_render_8bpp; + if (mach->regs[0xb8] & 0x40) + svga->clock *= 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; } - mach_log("BPP=%d, VRAM Mask=%08x, NormalPitch=%d, CRTPitch=%d, VSYNCSTART=%d, VTOTAL=%d, ROWCOUNT=%d, mode=%d, highres bit=%x, has_vga?=%d, override=%d.\n", svga->bpp, svga->vram_mask, dev->pitch, dev->ext_crt_pitch, svga->vsyncstart, svga->vtotal, svga->rowcount, dev->ibm_mode, dev->accel.advfunc_cntl & 4, ibm8514_has_vga, svga->override); } - mach_log("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", svga->hdisp, svga->vtotal, svga->htotal, svga->dispend, svga->rowoffset, svga->split, svga->vsyncstart, svga->split); } } static void -mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, uint32_t val, int len) +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 { + } 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); } @@ -2784,9 +2873,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xc6e8: 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: @@ -2800,7 +2888,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (len == 1) dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val; else { - mach->accel.src_y = val; + mach->accel.src_y = val; + dev->accel.desty = val & 0x07ff; dev->accel.desty_axstp = val & 0x3fff; if (val & 0x2000) dev->accel.desty_axstp |= ~0x1fff; @@ -2820,7 +2909,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (len == 1) dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val; else { - mach->accel.src_x = val; + mach->accel.src_x = val; + dev->accel.destx = val & 0x07ff; dev->accel.destx_distp = val & 0x3fff; if (val & 0x2000) dev->accel.destx_distp |= ~0x1fff; @@ -2838,11 +2928,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x92e8: if (len != 1) dev->test = val; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; + case 0xd2e8: - mach_log("92E8 = %04x\n", val); if (len == 1) dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; else { @@ -2865,8 +2953,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (len == 1) dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0x0700) | val; else { - mach->accel.test = val & 0x1fff; + mach->accel.test = val & 0x1fff; dev->accel.maj_axis_pcnt = val & 0x07ff; + dev->accel.maj_axis_pcnt_no_limit = val; } break; case 0x96e9: @@ -2885,7 +2974,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->data_available = 0; dev->data_available2 = 0; dev->accel.cmd = val; - mach_log("CMD8514 = %04x.\n", 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) @@ -2978,7 +3067,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (mach->accel.cmd_type >= 0) { if (mach_pixel_read(mach)) break; - mach_accel_out_pixtrans(mach, dev, port, val, len); + mach_accel_out_pixtrans(mach, dev, val); } else { if (ibm8514_cpu_dest(svga)) break; @@ -3005,31 +3094,31 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u 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; + 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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: @@ -3063,7 +3152,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (mach->accel.cmd_type >= 0) { if (mach_pixel_read(mach)) break; - mach_accel_out_pixtrans(mach, dev, port, val, len); + mach_accel_out_pixtrans(mach, dev, val); } else { if (ibm8514_cpu_dest(svga)) break; @@ -3090,31 +3179,31 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u 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; + 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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: @@ -3133,8 +3222,10 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xeae8: if (len == 1) dev->accel.wrt_mask = (dev->accel.wrt_mask & 0x00ff) | val; - else + else { dev->accel.wrt_mask = val; + mach_log("WrtMask=%04x.\n", val); + } break; case 0xaae9: case 0xeae9: @@ -3146,8 +3237,10 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xeee8: if (len == 1) dev->accel.rd_mask = (dev->accel.rd_mask & 0x00ff) | val; - else + else { dev->accel.rd_mask = val; + mach_log("ReadMask=%04x.\n", val); + } break; case 0xaee9: case 0xeee9: @@ -3197,10 +3290,11 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u 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], svga->bpp, dev->pitch); + 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 || !dev->ext_crt_pitch) + if (dev->local < 2) dev->ext_crt_pitch = 128; + svga_recalctimings(svga); } if (port == 0xfee8) @@ -3221,8 +3315,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; } if ((dev->accel.multifunc_cntl >> 12) == 5) { - if (!dev->local || !dev->ext_crt_pitch) + if (dev->local < 2) dev->ext_crt_pitch = 128; + svga_recalctimings(svga); } if (port == 0xfee9) @@ -3232,7 +3327,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } break; -/*ATI Mach8/32 specific registers*/ + /*ATI Mach8/32 specific registers*/ case 0x82ee: mach->accel.patt_data_idx = val & 0x1f; mach_log("Pattern Data Index = %d.\n", val & 0x1f); @@ -3242,22 +3337,21 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u 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] = 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 ((svga->bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { + 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 (svga->bpp == 24) + 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); } @@ -3270,7 +3364,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & 7; else { frgd_sel = (mach->accel.dp_config >> 13) & 7; - if ((svga->bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { + if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { mach->accel.patt_data_idx += 2; dev->accel.y1 = 1; } else @@ -3284,11 +3378,11 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach->accel.bres_count = (mach->accel.bres_count & 0x700) | val; else { mach->accel.bres_count = val & 0x7ff; - mach_log("96EE line draw.\n"); + 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, len); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); } break; case 0x96ef: @@ -3298,7 +3392,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u 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, len); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); } break; @@ -3312,6 +3406,16 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u 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: @@ -3344,7 +3448,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0xaeee: - mach_log("AEEE write val = %04x.\n", val); if (len == 1) mach->accel.dest_y_end = (mach->accel.dest_y_end & 0x700) | val; else { @@ -3357,16 +3460,16 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u 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, len); + 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, len); + 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; @@ -3411,7 +3514,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0xcaee: - mach_log("CAEE write val = %04x.\n", val); if (len == 1) mach->accel.scan_to_x = (mach->accel.scan_to_x & 0x700) | val; else { @@ -3424,16 +3526,16 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u 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, len); + 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, len); + 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; @@ -3442,6 +3544,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u 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; @@ -3547,17 +3651,16 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0xfeee: - if (mach->accel.dp_config == 0x2231 || mach->accel.dp_config == 0x2211) - mach_log("FEEE val = %d, lineidx = %d, DPCONFIG = %04x, CPUCX = %04x.\n", val, mach->accel.line_idx, mach->accel.dp_config, CX); + 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]; + 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, len); + 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; } @@ -3571,672 +3674,367 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } static void -mach_accel_out(uint16_t port, uint32_t val, mach_t *mach, int len) -{ - svga_t *svga = &mach->svga; - ibm8514_t *dev = &svga->dev8514; - - mach_log("Port accel out = %04x, val = %04x, len = %d.\n", port, val, len); - - if (port & 0x8000) { - mach_accel_out_fifo(mach, svga, dev, port, val, len); - } 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); - mach_log("ATI 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1); - svga_recalctimings(svga); - } - break; - - case 0x6e8: - dev->hdisp = val; - mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); - svga_recalctimings(svga); - break; - - case 0xae8: - mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); - svga_recalctimings(svga); - break; - - case 0xee8: - mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); - svga_recalctimings(svga); - 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); - mach_log("ATI 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal); - svga_recalctimings(svga); - } - 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); - mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); - svga_recalctimings(svga); - } - 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); - mach_log("ATI 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart); - svga_recalctimings(svga); - } - break; - - case 0x1ee8: - dev->vsyncwidth = val; - mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); - svga_recalctimings(svga); - break; - - case 0x22e8: - dev->disp_cntl = val & 0x7e; - dev->interlace = !!(val & 0x10); - mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); - svga_recalctimings(svga); - break; - - case 0x42e8: - if (len == 1) { - dev->subsys_stat &= ~val; - } else { - dev->subsys_stat &= ~(val & 0xff); - dev->subsys_cntl = (val >> 8); - mach_log("CNTL = %02x.\n", val >> 8); - } - break; - case 0x42e9: - if (len == 1) { - dev->subsys_cntl = val; - mach_log("CNTL = %02x.\n", val); - } - break; - - case 0x4ae8: - mach_log("ATI 8514/A: VGA ON (0x4ae8) = %i, val = %02x\n", vga_on, val); - if (!val) - break; - if (!dev->local || !dev->ext_crt_pitch) - dev->ext_crt_pitch = 128; - dev->accel.advfunc_cntl = val & 7; - ibm8514_on = (dev->accel.advfunc_cntl & 1); - vga_on = !ibm8514_on; - dev->ibm_mode = 1; - if (ibm8514_on) - svga->adv_flags |= FLAG_ATI; - else - svga->adv_flags &= ~FLAG_ATI; - svga_recalctimings(svga); - break; - - /*ATI Mach8/32 specific registers*/ - case 0x6ee: - mach_log("6EE write val = %02x, len = %d.\n", val, len); - break; - - case 0x6ef: - mach_log("6EF write val = %02x, len = %d.\n", val, len); - break; - - case 0xaee: - if (len == 1) - mach->cursor_offset_lo = (mach->cursor_offset_lo & 0xff00) | val; - else { - mach_log("AEE val=%02x.\n", val); - mach->cursor_offset_lo = val; - svga->hwcursor.addr = mach->cursor_offset_lo << 2; - } - break; - case 0xaef: - if (len == 1) { - mach->cursor_offset_lo = (mach->cursor_offset_lo & 0x00ff) | (val << 8); - svga->hwcursor.addr = mach->cursor_offset_lo << 2; - } - break; - - case 0xeee: - mach->cursor_offset_hi = val & 0x0f; - if (len != 1) { - svga->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16))) << 2; - svga->hwcursor.ena = !!(val & 0x8000); - } - mach_log("EEE val=%08x.\n", svga->hwcursor.addr); - break; - case 0xeef: - if (len == 1) { - svga->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16))) << 2; - svga->hwcursor.ena = !!(val & 0x80); - } - break; - - case 0x12ee: - if (len == 1) { - svga->hwcursor.x = (svga->hwcursor.x & 0x700) | val; - } else { - svga->hwcursor.x = val & 0x7ff; - mach_log("X = %03x.\n", val); - } - break; - case 0x12ef: - if (len == 1) { - svga->hwcursor.x = (svga->hwcursor.x & 0x0ff) | ((val & 0x07) << 8); - } - break; - - case 0x16ee: - if (len == 1) { - svga->hwcursor.y = (svga->hwcursor.y & 0xf00) | val; - } else { - svga->hwcursor.y = val & 0xfff; - } - break; - case 0x16ef: - if (len == 1) { - svga->hwcursor.y = (svga->hwcursor.y & 0x0ff) | ((val & 0x0f) << 8); - } - break; - - case 0x1aee: - if (len != 1) { - mach->cursor_col_0 = val & 0xff; - mach->cursor_col_1 = (val >> 8) & 0xff; - } else - mach->cursor_col_0 = val; - break; - case 0x1aef: - if (len == 1) - mach->cursor_col_1 = val; - break; - - case 0x1eee: - if (len != 1) { - svga->hwcursor.xoff = val & 0x3f; - svga->hwcursor.yoff = (val >> 8) & 0x3f; - } else - svga->hwcursor.xoff = val & 0x3f; - break; - case 0x1eef: - if (len == 1) - svga->hwcursor.yoff = val & 0x3f; - break; - - case 0x2aee: - mach_log("2AEE write val = %04x\n", val); - if (len == 1) - mach->accel.crt_offset_lo = (mach->accel.crt_offset_lo & 0xff00) | val; - else - mach->accel.crt_offset_lo = val; - break; - case 0x2aef: - if (len == 1) - mach->accel.crt_offset_lo = (mach->accel.crt_offset_lo & 0x00ff) | (val << 8); - break; - - case 0x2eee: - mach_log("2EEE write val = %04x\n", val); - if (len == 1) - mach->accel.crt_offset_hi = (mach->accel.crt_offset_hi & 0xff00) | val; - else - mach->accel.crt_offset_hi = val; - break; - case 0x2eef: - if (len == 1) - mach->accel.crt_offset_hi = (mach->accel.crt_offset_hi & 0x00ff) | (val << 8); - break; - - case 0x26ee: - mach_log("CRT Pitch = %d, original val = %d.\n", val << 3, val); - dev->ext_crt_pitch = val; - dev->internal_pitch = val; - if (svga->bpp > 8) { - if (svga->bpp == 24) - dev->ext_crt_pitch *= 3; - else - dev->ext_crt_pitch <<= 1; - } - if (dev->local) { - if (!ibm8514_on) { - ibm8514_on ^= 1; - svga->adv_flags |= FLAG_ATI; - } - } - svga_recalctimings(svga); - break; - - case 0x32ee: - if (len == 1) { - mach->local_cntl = (mach->local_cntl & 0xff00) | val; - } else { - mach->local_cntl = val; - mach32_updatemapping(mach); - } - break; - - case 0x32ef: - if (len == 1) { - mach->local_cntl = (mach->local_cntl & 0x00ff) | (val << 8); - mach32_updatemapping(mach); - } - break; - - case 0x36ee: - if (len == 1) { - mach->misc = (mach->misc & 0xff00) | (val); - } else { - mach->misc = val; - } - break; - case 0x36ef: - if (len == 1) { - mach->misc = (mach->misc & 0x00ff) | (val << 8); - } - break; - - case 0x3aee: - if (len == 1) { - mach->ext_cur_col_0_g = val; - } else { - mach->ext_cur_col_0_g = val & 0xff; - mach->ext_cur_col_0_r = (val >> 8) & 0xff; - } - break; - case 0x3aef: - if (len == 1) { - mach->ext_cur_col_0_r = val; - } - break; - - case 0x3eee: - if (len == 1) { - mach->ext_cur_col_1_g = val; - } else { - mach->ext_cur_col_1_g = val & 0xff; - mach->ext_cur_col_1_r = (val >> 8) & 0xff; - } - break; - case 0x3eef: - if (len == 1) { - mach->ext_cur_col_1_r = val; - } - break; - - case 0x42ee: - mach->accel.test2[0] = val; - break; - case 0x42ef: - mach->accel.test2[1] = val; - break; - - case 0x46ee: - mach->accel.test3[0] = val; - break; - case 0x46ef: - mach->accel.test3[1] = val; - break; - - case 0x4aee: - if (len == 1) - mach->accel.clock_sel = (mach->accel.clock_sel & 0xff00) | val; - else { - mach->accel.clock_sel = val; - ibm8514_on = (mach->accel.clock_sel & 1); - vga_on = !ibm8514_on; - dev->ibm_mode = 0; - if (ibm8514_on) - svga->adv_flags |= FLAG_ATI; - else - svga->adv_flags &= ~FLAG_ATI; - mach_log("ATI 8514/A: VGA ON (0x4aee) = %i, val = %04x\n", vga_on, val); - svga_recalctimings(svga); - } - break; - case 0x4aef: - if (len == 1) { - mach->accel.clock_sel = (mach->accel.clock_sel & 0x00ff) | (val << 8); - ibm8514_on = (mach->accel.clock_sel & 1); - vga_on = !ibm8514_on; - dev->ibm_mode = 0; - if (ibm8514_on) - svga->adv_flags |= FLAG_ATI; - else - svga->adv_flags &= ~FLAG_ATI; - mach_log("ATI 8514/A: VGA ON (0x4aef) = %i, val = %04x\n", vga_on, mach->accel.clock_sel); - svga_recalctimings(svga); - } - break; - - case 0x52ee: - if (len == 1) - mach->accel.scratch0 = (mach->accel.scratch0 & 0xff00) | val; - else - mach->accel.scratch0 = val; - break; - case 0x52ef: - if (len == 1) - mach->accel.scratch0 = (mach->accel.scratch0 & 0x00ff) | (val << 8); - break; - - case 0x56ee: - if (len == 1) - mach->accel.scratch1 = (mach->accel.scratch1 & 0xff00) | val; - else - mach->accel.scratch1 = val; - break; - case 0x56ef: - if (len == 1) - mach->accel.scratch1 = (mach->accel.scratch1 & 0x00ff) | (val << 8); - break; - - case 0x5aee: - mach_log("Shadow set = %04x\n", val); - break; - case 0x5aef: - mach_log("Shadow + 1 set = %02x\n", val); - break; - - case 0x5eee: - mach_log("Memory Aperture = %04x, len = %d.\n", val, len); - if (len == 1) { - mach->memory_aperture = (mach->memory_aperture & 0xff00) | val; - } else { - mach->memory_aperture = val; - if (!mach->pci_bus) - mach->linear_base = (mach->memory_aperture & 0xff00) << 12; - - mach32_updatemapping(mach); - } - break; - - case 0x5eef: - if (len == 1) { - mach->memory_aperture = (mach->memory_aperture & 0x00ff) | (val << 8); - if (!mach->pci_bus) - mach->linear_base = (mach->memory_aperture & 0xff00) << 12; - - mach32_updatemapping(mach); - } - 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: - mach_log("6AEE write val = %04x.\n", val & 0x400); - if (len == 1) - mach->accel.max_waitstates = (mach->accel.max_waitstates & 0xff00) | val; - else { - mach->accel.max_waitstates = val; - } - break; - case 0x6aef: - if (len == 1) - mach->accel.max_waitstates = (mach->accel.max_waitstates & 0x00ff) | (val << 8); - break; - - case 0x6eee: - mach_log("6EEE write val = %04x\n", val); - if (len == 1) - mach->accel.ge_offset_lo = (mach->accel.ge_offset_lo & 0xff00) | val; - else { - mach->accel.ge_offset_lo = val; - dev->accel.ge_offset = mach->accel.ge_offset_lo; - } - break; - case 0x6eef: - if (len == 1) { - mach->accel.ge_offset_lo = (mach->accel.ge_offset_lo & 0x00ff) | (val << 8); - dev->accel.ge_offset = mach->accel.ge_offset_lo; - } - break; - - case 0x72ee: - mach_log("72EE write val = %04x\n", val); - if (len == 1) - mach->accel.ge_offset_hi = (mach->accel.ge_offset_hi & 0xff00) | val; - else { - mach->accel.ge_offset_hi = val; - dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); - } - break; - case 0x72ef: - if (len == 1) { - mach->accel.ge_offset_hi = (mach->accel.ge_offset_hi & 0x00ff) | (val << 8); - dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); - } - break; - - case 0x76ee: - mach_log("76EE write val=%d shifted, normal=%d.\n", val << 3, val); - dev->ext_pitch = val << 3; - svga_recalctimings(svga); - break; - - case 0x7aee: - mach_log("7AEE write val = %04x, len = %d.\n", val, len); - if (len == 1) - mach->accel.ext_ge_config = (mach->accel.ext_ge_config & 0xff00) | val; - else { - mach->accel.ext_ge_config = val; - dev->ext_crt_pitch = dev->internal_pitch; - switch (mach->accel.ext_ge_config & 0x30) { - case 0: - case 0x10: - svga->bpp = 8; - break; - case 0x20: - if ((mach->accel.ext_ge_config & 0xc0) == 0x40) - svga->bpp = 16; - else - svga->bpp = 15; - - dev->ext_crt_pitch <<= 1; - break; - case 0x30: - svga->bpp = 24; - dev->ext_crt_pitch *= 3; - break; - - default: - break; - } - if (mach->accel.ext_ge_config & 0x800) { - svga_recalctimings(svga); - } - if (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800)) - svga_recalctimings(svga); - } - break; - case 0x7aef: - mach_log("7AEF write val = %02x.\n", val); - if (len == 1) { - mach->accel.ext_ge_config = (mach->accel.ext_ge_config & 0x00ff) | (val << 8); - dev->ext_crt_pitch = dev->internal_pitch; - switch (mach->accel.ext_ge_config & 0x30) { - case 0: - case 0x10: - svga->bpp = 8; - break; - case 0x20: - if ((mach->accel.ext_ge_config & 0xc0) == 0x40) - svga->bpp = 16; - else - svga->bpp = 15; - - dev->ext_crt_pitch <<= 1; - break; - case 0x30: - svga->bpp = 24; - dev->ext_crt_pitch *= 3; - break; - - default: - break; - } - if (mach->accel.ext_ge_config & 0x800) { - svga_recalctimings(svga); - } - if (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800)) - svga_recalctimings(svga); - } - break; - - case 0x7eee: - mach->accel.eeprom_control = val; - break; - - default: - break; - } - } -} - -static uint32_t -mach_accel_in(uint16_t port, mach_t *mach, int len) +mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) { svga_t *svga = &mach->svga; - ibm8514_t *dev = &svga->dev8514; - uint16_t *vram_w = (uint16_t *) svga->vram; - uint16_t temp = 0; - int cmd; - int vpos = dev->displine + svga->y_add; - int vblankend = svga->vblankstart + svga->crtc[0x16]; - int frgd_sel; - int bkgd_sel; - int mono_src; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t old = 0; + + mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); switch (port) { case 0x2e8: - if (dev->local) { - vpos = svga->displine + svga->y_add; - if (vblankend > svga->vtotal) { - vblankend -= svga->vtotal; - if (vpos >= svga->vblankstart || vpos <= vblankend) - temp |= 2; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - temp |= 2; - } - } else { - vpos = dev->displine + svga->y_add; - if (vblankend > dev->vtotal) { - vblankend -= dev->vtotal; - if (vpos >= svga->vblankstart || vpos <= vblankend) - temp |= 2; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - temp |= 2; - } + case 0x2e9: + WRITE8(port, dev->htotal, val); + svga_recalctimings(svga); + break; + case 0x6e8: + case 0x6e9: + if (!(port & 1)) { + if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0)) + dev->hdisp = val; + else if (!dev->on[0] || !dev->on[1]) + dev->hdisp = val; + + mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); } + svga_recalctimings(svga); break; - case 0x6e8: - temp = dev->hdisp; + case 0xae8: + mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + svga_recalctimings(svga); + break; + + case 0xee8: + mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + svga_recalctimings(svga); + break; + + case 0x12e8: + case 0x12e9: + WRITE8(port, dev->vtotal, val); + dev->vtotal &= 0x1fff; + svga_recalctimings(svga); + break; + + case 0x16e8: + case 0x16e9: + if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0)) { + WRITE8(port, dev->vdisp, val); + } else if (!dev->on[0] || !dev->on[1]) { + WRITE8(port, dev->vdisp, val); + } + dev->vdisp &= 0x1fff; + mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", (dev->vdisp >> 1) + 1); + svga_recalctimings(svga); + break; + + case 0x1ae8: + case 0x1ae9: + WRITE8(port, dev->vsyncstart, val); + dev->vsyncstart &= 0x1fff; + svga_recalctimings(svga); + break; + + case 0x1ee8: + case 0x1ee9: + mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); + svga_recalctimings(svga); break; case 0x22e8: - temp = dev->disp_cntl; - break; - - case 0x26e8: - if (len == 1) - temp = dev->htotal & 0xff; - else - temp = dev->htotal; - break; - case 0x26e9: - if (len == 1) - temp = dev->htotal >> 8; - break; - - case 0x2ee8: - temp = dev->subsys_cntl; + dev->disp_cntl = val & 0x7e; + dev->interlace = !!(val & 0x10); + svga_recalctimings(svga); + mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); break; case 0x42e8: - if (dev->local) { - vpos = svga->displine + svga->y_add; - if (vblankend > svga->vtotal) { - vblankend -= svga->vtotal; - if (vpos >= svga->vblankstart || vpos <= vblankend) - dev->subsys_stat |= 1; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - dev->subsys_stat |= 1; - } - } else { - vpos = dev->displine + svga->y_add; - if (vblankend > dev->vtotal) { - vblankend -= dev->vtotal; - if (vpos >= svga->vblankstart || vpos <= vblankend) - dev->subsys_stat |= 1; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - dev->subsys_stat |= 1; - } - } - - if (len != 1) { - temp = dev->subsys_stat | 0xa0 | 0x8000; - } else { - temp = dev->subsys_stat | 0xa0; - } + 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: - temp = dev->accel.advfunc_cntl; + case 0x4ae9: + if (dev->local < 2) + dev->ext_crt_pitch = 128; + + WRITE8(port, dev->accel.advfunc_cntl, val); + dev->on[port & 1] = (dev->accel.advfunc_cntl & 0x01); + mach_log("ATI 8514/A: (0x%04x): ON=%d.\n", port, dev->on[port & 1]); + vga_on = !dev->on[port & 1]; + mach->ext_on[port & 1] = dev->on[port & 1]; + mach32_updatemapping(mach); + dev->vendor_mode[port & 1] = 0; + svga_recalctimings(svga); break; - case 0x42e9: - if (len == 1) { - temp = dev->subsys_stat >> 8; - temp |= 0x80; + /*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); } 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); + 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: + WRITE8(port, mach->accel.test2, val); + break; + + case 0x46ee: + case 0x46ef: + WRITE8(port, mach->accel.test3, 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: + WRITE8(port, mach->shadow_set, val); + mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + if (mach->shadow_set & 3) + svga_recalctimings(svga); + 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); + 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.\n", port, val); + 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); + } + mach_log("ATI 8514/A: (0x%04x) val = %02x.\n", port, val); + svga_recalctimings(svga); + break; + + case 0x7eee: + case 0x7eef: + WRITE8(port, mach->accel.eeprom_control, val); + ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 4, 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 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) { @@ -4332,31 +4130,25 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) if (mach_pixel_read(mach)) { cmd = -1; if (len == 1) { - READ_PIXTRANS_BYTE_IO(dev->accel.dx, 1, dev->local) - + 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, dev->local) + READ_PIXTRANS_WORD(dev->accel.cx, 0) } else { - READ_PIXTRANS_WORD(dev->accel.dx, 0, dev->local) + READ_PIXTRANS_WORD(dev->accel.dx, 0) } - mach_accel_out_pixtrans(mach, dev, port, temp, len); + mach_accel_out_pixtrans(mach, dev, temp); } } } else { if (ibm8514_cpu_dest(svga)) { cmd = (dev->accel.cmd >> 13); - if (len == 1) { - ; // READ_PIXTRANS_BYTE_IO(0) - } else { - READ_PIXTRANS_WORD(dev->accel.cx, 0, dev->local) + if (len != 1) { + READ_PIXTRANS_WORD(dev->accel.cx, 0) if (dev->accel.input && !dev->accel.odd_in && !dev->accel.sx) { temp &= ~0xff00; - if (dev->local) - temp |= (svga->vram[(dev->accel.newdest_in + dev->accel.cur_x) & svga->vram_mask] << 8); - else - temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); + temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); } if (dev->subsys_stat & 1) { dev->force_busy = 1; @@ -4374,7 +4166,7 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) if (mach_pixel_read(mach)) { if (len == 1) { cmd = -1; - READ_PIXTRANS_BYTE_IO(dev->accel.dx, 0, dev->local) + READ_PIXTRANS_BYTE_IO(dev->accel.dx, 0) temp = mach->accel.pix_trans[0]; frgd_sel = (mach->accel.dp_config >> 13) & 7; @@ -4385,23 +4177,23 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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, len); + 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: @@ -4451,198 +4243,22 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) } break; -/*ATI Mach8/32 specific registers*/ - case 0x12ee: - if (len == 1) - temp = mach->config1 & 0xff; - else - temp = mach->config1; - break; - case 0x12ef: - if (len == 1) - temp = mach->config1 >> 8; - break; - - case 0x16ee: - if (len == 1) - temp = mach->config2 & 0xff; - else - temp = mach->config2; - break; - case 0x16ef: - if (len == 1) - temp = mach->config2 >> 8; - break; - - case 0x32ee: - if (len == 1) - temp = mach->local_cntl & 0xff; - else - temp = mach->local_cntl; - break; - case 0x32ef: - if (len == 1) - temp = mach->local_cntl >> 8; - break; - - case 0x36ee: - if (len == 1) - temp = mach->misc & 0xff; - else - temp = mach->misc; - break; - case 0x36ef: - if (len == 1) - temp = mach->misc >> 8; - break; - - case 0x42ee: - temp = mach->accel.test2[0]; - break; - case 0x42ef: - temp = mach->accel.test2[1]; - break; - - case 0x46ee: - temp = mach->accel.test3[0]; - break; - case 0x46ef: - temp = mach->accel.test3[1]; - break; - - case 0x4aee: - if (len == 1) - temp = mach->accel.clock_sel & 0xff; - else - temp = mach->accel.clock_sel; - break; - case 0x4aef: - if (len == 1) - temp = mach->accel.clock_sel >> 8; - break; - - case 0x52ee: - if (len == 1) - temp = mach->accel.scratch0 & 0xff; - else - temp = mach->accel.scratch0; - break; - case 0x52ef: - if (len == 1) - temp = mach->accel.scratch0 >> 8; - break; - - case 0x56ee: - if (len == 1) - temp = mach->accel.scratch1 & 0xff; - else - temp = mach->accel.scratch1; - break; - case 0x56ef: - if (len == 1) - temp = mach->accel.scratch1 >> 8; - break; - - case 0x5eee: - if (mach->pci_bus) - mach->memory_aperture = (mach->memory_aperture & ~0xfff0) | ((mach->linear_base >> 20) << 4); - - if (len == 1) - temp = mach->memory_aperture & 0xff; - else - temp = mach->memory_aperture; - break; - case 0x5eef: - if (len == 1) - temp = mach->memory_aperture >> 8; - break; - - case 0x62ee: - temp = mach->accel.clip_overrun; - if (len != 1) { - if (mach->force_busy) - temp |= 0x2000; - mach->force_busy = 0; - if (ati_eeprom_read(&mach->eeprom)) - temp |= 0x4000; - } - mach_log("[%04X:%08X]: 62EE: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); - break; - case 0x62ef: - if (len == 1) { - if (mach->force_busy2) - temp |= 0x20; - mach->force_busy2 = 0; - if (ati_eeprom_read(&mach->eeprom)) - temp |= 0x40; - } - mach_log("[%04X:%08X]: 62EF: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); - break; - - case 0x6aee: - if (len == 1) - temp = mach->accel.max_waitstates & 0xff; - else - temp = mach->accel.max_waitstates; - break; - case 0x6aef: - if (len == 1) - temp = mach->accel.max_waitstates >> 8; - break; - - case 0x72ee: - if (len == 1) - temp = dev->accel.clip_left & 0xff; - else - temp = dev->accel.clip_left; - break; - case 0x72ef: - if (len == 1) - temp = dev->accel.clip_left >> 8; - break; - - case 0x76ee: - if (len == 1) - temp = dev->accel.clip_top & 0xff; - else - temp = dev->accel.clip_top; - break; - case 0x76ef: - if (len == 1) - temp = dev->accel.clip_top >> 8; - break; - - case 0x7aee: - if (len == 1) - temp = dev->accel.multifunc[4] & 0xff; - else - temp = dev->accel.multifunc[4]; - break; - case 0x7aef: - if (len == 1) - temp = dev->accel.multifunc[4] >> 8; - break; - - case 0x7eee: - if (len == 1) - temp = dev->accel.multifunc[3] & 0xff; - else - temp = dev->accel.multifunc[3]; - break; - case 0x7eef: - if (len == 1) - temp = dev->accel.multifunc[3] >> 8; - 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) @@ -4650,7 +4266,18 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) break; case 0x92ee: - temp = mach->accel.eeprom_control; + 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: @@ -4733,40 +4360,39 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) case 0xceee: if (len == 1) - temp = svga->vc & 0xff; + temp = dev->vc & 0xff; else - temp = svga->vc & 0x7ff; + temp = dev->vc & 0x7ff; break; case 0xceef: if (len == 1) - temp = (svga->vc >> 8) & 7; + temp = (dev->vc >> 8) & 7; break; case 0xdaee: if (len != 1) { temp = mach->accel.src_x; - if (dev->local) { + if ((dev->local & 0xff) >= 0x02) temp &= 0x7ff; - } } else - temp = dev->accel.destx_distp & 0xff; + temp = mach->accel.src_x & 0xff; break; case 0xdaef: if (len == 1) - temp = dev->accel.destx_distp >> 8; + temp = mach->accel.src_x >> 8; break; case 0xdeee: if (len != 1) { temp = mach->accel.src_y; - if (dev->local) + if ((dev->local & 0xff) >= 0x02) temp &= 0x7ff; } else - temp = dev->accel.desty_axstp & 0xff; + temp = mach->accel.src_y & 0xff; break; case 0xdeef: if (len == 1) - temp = dev->accel.desty_axstp >> 8; + temp = mach->accel.src_y >> 8; break; case 0xfaee: @@ -4794,9 +4420,201 @@ mach_accel_in(uint16_t port, mach_t *mach, int len) default: break; } - if (port != 0x9ae8 && port != 0x9ae9 && port != 0x62ee && port != 0x9aee) { - mach_log("Port accel in = %04x, temp = %04x, len = %d, mode = %d.\n", port, temp, len, dev->ibm_mode); + + 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(uint16_t port, mach_t *mach) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + 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->hdisp; + 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 (!(dev->subsys_stat & 1)) { + 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; + } + 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)) { + switch (mach->memory) { + case 512: + temp &= ~0x0c; + break; + case 1024: + temp |= 0x04; + break; + case 2048: + temp |= 0x08; + break; + case 4096: + temp |= 0x0c; + break; + + default: + break; + } + } + break; + + case 0x42ee: + case 0x42ef: + READ8(port, mach->accel.test2); + break; + + case 0x46ee: + case 0x46ef: + READ8(port, mach->accel.test3); + break; + + case 0x4aee: + case 0x4aef: + READ8(port, mach->accel.clock_sel); + break; + + case 0x52ee: + case 0x52ef: + READ8(port, mach->accel.scratch0); + 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; } + mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp); return temp; } @@ -4804,37 +4622,427 @@ static void mach_accel_outb(uint16_t port, uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach_accel_out(port, val, mach, 1); + 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; - mach_accel_out(port, val, mach, 2); + 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); + } +} static uint8_t mach_accel_inb(uint16_t port, void *priv) { mach_t *mach = (mach_t *) priv; - return mach_accel_in(port, mach, 1); + 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; - return mach_accel_in(port, mach, 2); + 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; - uint8_t port_dword = addr & 0xfc; + 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 ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + 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); @@ -4843,18 +5051,24 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv) mach_accel_outb(0x02e8 + (addr & 1) + (port_dword << 8), val, mach); } } else { - mach_log("Linear WORDB Write=%08x.\n", addr); - svga_write_linear(addr, val, &mach->svga); + 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; - uint8_t port_dword = addr & 0xfc; + 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 ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + 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); @@ -4863,18 +5077,25 @@ mach32_ap_writew(uint32_t addr, uint16_t val, void *priv) mach_accel_outw(0x02e8 + (port_dword << 8), val, mach); } } else { - mach_log("Linear WORDW Write=%08x.\n", addr); - svga_writew_linear(addr, val, &mach->svga); + 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; - uint8_t port_dword = addr & 0xfc; + 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 ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + 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); @@ -4885,26 +5106,40 @@ mach32_ap_writel(uint32_t addr, uint32_t val, void *priv) mach_accel_outw(0x02e8 + (port_dword << 8) + 4, val >> 16, mach); } } else { - mach_log("Linear WORDL Write=%08x, val=%08x, mode=%d, rop=%02x.\n", addr, val, mach->svga.writemode, mach->svga.gdcreg[3] & 0x18); - svga_writel_linear(addr, val, &mach->svga); + 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; + 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; + uint8_t port_dword = addr & 0xfc; - if ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { - if (addr & 0x100) { + 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 { + else temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach); - } - } else - temp = svga_read_linear(addr, &mach->svga); + } 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; } @@ -4912,18 +5147,27 @@ mach32_ap_readb(uint32_t addr, void *priv) static uint16_t mach32_ap_readw(uint32_t addr, void *priv) { - mach_t *mach = (mach_t *) 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; + uint8_t port_dword = addr & 0xfc; - if ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { - if (addr & 0x100) { + 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 { + else temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); - } - } else - temp = svga_readw_linear(addr, &mach->svga); + } 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; } @@ -4931,11 +5175,14 @@ mach32_ap_readw(uint32_t addr, void *priv) static uint32_t mach32_ap_readl(uint32_t addr, void *priv) { - mach_t *mach = (mach_t *) 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; + uint8_t port_dword = addr & 0xfc; - if ((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20))) { + 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); @@ -4943,8 +5190,17 @@ mach32_ap_readl(uint32_t addr, void *priv) temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); temp |= (mach_accel_inw(0x02e8 + (port_dword << 8) + 4, mach) << 8); } - } else - temp = svga_readl_linear(addr, &mach->svga); + } 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; } @@ -4953,6 +5209,7 @@ static void mach32_updatemapping(mach_t *mach) { svga_t *svga = &mach->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); @@ -4963,7 +5220,6 @@ mach32_updatemapping(mach_t *mach) if (mach->regs[0xbd] & 4) { mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; - mach_log("Bit 2 of BD.\n"); } else { switch (svga->gdcreg[6] & 0x0c) { case 0x0: /*128k at A0000*/ @@ -4999,65 +5255,80 @@ mach32_updatemapping(mach_t *mach) mach->ap_size = 4; mem_mapping_set_addr(&mach->mmio_linear_mapping, mach->linear_base, mach->ap_size << 20); } - /*Force IBM/ATI mode on when the MMIO registers are loaded.*/ - if (mach->local_cntl & 0x20) { - if (!ibm8514_on) { - ibm8514_on ^= 1; - svga->adv_flags |= FLAG_ATI; - svga_recalctimings(svga); - } - } } 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) { - mach_t *mach = (mach_t *) svga->priv; - uint16_t dat; - int comb; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t color0; - uint32_t color1; + 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; - if (svga->bpp == 8) { - color0 = svga->pallook[mach->cursor_col_0]; - color1 = svga->pallook[mach->cursor_col_1]; - mach_log("8BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); - } else if (svga->bpp == 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]; - mach_log("15BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); - } else if (svga->bpp == 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]; - mach_log("16BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); - } else { - 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); - mach_log("24BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); + 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 (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + if (dev->interlace && dev->hwcursor_oddeven) + dev->hwcursor_latch.addr += 16; for (int x = 0; x < 64; x += 8) { - dat = svga->vram[svga->hwcursor_latch.addr & svga->vram_mask] | (svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_mask] << 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; - if (offset >= svga->hwcursor_latch.x) { + + 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: - (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = color0; + p[x_pos] = color0; break; case 1: - (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = color1; + p[x_pos] = color1; break; case 3: - (svga->monitor->target_buffer->line[displine])[offset + svga->x_add] ^= 0xffffff; + p[x_pos] ^= 0xffffff; break; default: @@ -5066,257 +5337,304 @@ mach32_hwcursor_draw(svga_t *svga, int displine) } offset++; } - svga->hwcursor_latch.addr += 2; + dev->hwcursor_latch.addr += 2; } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + if (dev->interlace && !dev->hwcursor_oddeven) + dev->hwcursor_latch.addr += 16; } +#if 0 static void mach_io_remove(mach_t *mach) { - io_removehandler(0x01ce, 2, - mach_in, NULL, NULL, - mach_out, NULL, NULL, mach); - io_removehandler(0x03c0, 32, - mach_in, NULL, NULL, - mach_out, NULL, NULL, mach); + io_removehandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x2ea, 0x0004, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); - io_removehandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_removehandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - - io_removehandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_removehandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x02ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x22ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); } +#endif static void mach_io_set(mach_t *mach) { - 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(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(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x2ea, 0x0004, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); - io_sethandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, 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(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, 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(0xfaee, 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); +} - io_sethandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); - io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, 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); } static uint8_t mach32_pci_read(UNUSED(int func), int addr, void *priv) { - mach_t *mach = (mach_t *) priv; - uint8_t ret = 0x00; + 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: @@ -5392,13 +5710,20 @@ 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; - mach_io_remove(mach); if (val & PCI_COMMAND_IO) { - mach_io_set(mach); + 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(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_removehandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); } mach32_updatemapping(mach); break; @@ -5438,43 +5763,55 @@ mach32_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) static void * mach8_init(const device_t *info) { - mach_t *mach; - svga_t *svga; + mach_t *mach; + svga_t *svga; ibm8514_t *dev; - uint32_t memory; - mach = malloc(sizeof(mach_t)); - memset(mach, 0x00, sizeof(mach_t)); + mach = calloc(1, sizeof(mach_t)); - svga = &mach->svga; - dev = &svga->dev8514; + 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); - dev->local = info->local; - 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; - memory = device_get_config_int("memory"); + 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) { - if (mach->vlb_bus) + 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->pci_bus) + else if (mach->mca_bus) { rom_init(&mach->bios_rom, - BIOS_MACH32_PCI_ROM_PATH, + BIOS_MACH32_MCA_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else + 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_ROM_PATH, @@ -5482,75 +5819,108 @@ mach8_init(const device_t *info) 0, MEM_MAPPING_EXTERNAL); } - svga_init(info, svga, mach, dev->local ? (memory << 10) : (512 << 10), /*default: 512kB for Mach8, 2MB for Mach32*/ - mach_recalctimings, - mach_in, mach_out, - dev->local ? mach32_hwcursor_draw : NULL, - NULL); - - if (dev->local) { - switch (memory) { - case 1024: - mach->misc |= 0x04; - break; - case 2048: - mach->misc |= 0x08; - break; - case 4096: - mach->misc |= 0x0c; - break; - - default: - break; - } - svga->hwcursor.cur_ysize = 64; + 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; - mach->config2 = 0x08; - /*Fake the RAMDAC to give the VLB/MCA variants full 24-bit support until said RAMDAC is implemented.*/ + 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); - mach->config1 |= 0x0c; + 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; - mach->config1 |= 0x0a00; + if (mach->ramdac_type) + mach->config1 |= 0x0400; + else + mach->config1 |= 0x0a00; mach->config2 |= 0x2000; - svga->ramdac = device_add(&ati68860_ramdac_device); + 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 = 0x02 | 0x20 | 0x80; mach->config2 = 0x02; - dev->ext_pitch = 1024; + 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; - ibm8514_enabled = 1; - ibm8514_has_vga = 1; - dev->ibm_mode = 1; - dev->rowoffset = 128; + 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) { - svga->decode_mask = (4 << 20) - 1; - mach->cursor_col_1 = 0xff; + 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; - dev->ext_crt_pitch = 128; if (mach->vlb_bus) ati_eeprom_load(&mach->eeprom, "mach32_vlb.nvr", 1); - else if (mach->pci_bus) { - ati_eeprom_load(&mach->eeprom, "mach32_pci.nvr", 1); + else if (mach->mca_bus) { + ati_eeprom_load(&mach->eeprom, "mach32_mca.nvr", 1); mem_mapping_disable(&mach->bios_rom.mapping); - mach->card = pci_add_card(PCI_ADD_VIDEO, mach32_pci_read, mach32_pci_write, mach); + 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; @@ -5582,6 +5952,12 @@ 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) { @@ -5591,13 +5967,15 @@ mach32_pci_available(void) static void mach_close(void *priv) { - mach_t *mach = (mach_t *) priv; - svga_t *svga = &mach->svga; - ibm8514_t *dev = &svga->dev8514; + 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); @@ -5619,7 +5997,7 @@ mach_force_redraw(void *priv) mach_t *mach = (mach_t *) priv; svga_t *svga = &mach->svga; - svga->fullchange = changeframecount; + svga->fullchange = svga->monitor->mon_changeframecount; } // clang-format off @@ -5656,11 +6034,64 @@ static const device_config_t mach32_config[] = { } }; +// 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_isa_device = { .name = "ATI Mach8 (ISA)", .internal_name = "mach8_isa", .flags = DEVICE_ISA, - .local = 0, + .local = 1, .init = mach8_init, .close = mach_close, .reset = NULL, @@ -5674,7 +6105,7 @@ const device_t mach32_isa_device = { .name = "ATI Mach32 (ISA)", .internal_name = "mach32_isa", .flags = DEVICE_ISA, - .local = 1, + .local = 2, .init = mach8_init, .close = mach_close, .reset = NULL, @@ -5688,7 +6119,7 @@ const device_t mach32_vlb_device = { .name = "ATI Mach32 (VLB)", .internal_name = "mach32_vlb", .flags = DEVICE_VLB, - .local = 1, + .local = 2, .init = mach8_init, .close = mach_close, .reset = NULL, @@ -5698,16 +6129,45 @@ const device_t mach32_vlb_device = { .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 = 1, + .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_config + .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 3f995c56a..f13740d34 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: @@ -73,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); @@ -110,9 +107,9 @@ att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) } 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); diff --git a/src/video/vid_att2xc498_ramdac.c b/src/video/vid_att2xc498_ramdac.c index 9919b7111..47eebccae 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); @@ -109,9 +106,9 @@ att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) } 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); diff --git a/src/video/vid_bt48x_ramdac.c b/src/video/vid_bt48x_ramdac.c index bb276ece6..91ddce956 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; @@ -85,9 +85,9 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *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; @@ -233,11 +233,11 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t * } 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; @@ -360,9 +360,9 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) } 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) @@ -386,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]; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 69d9609c6..2ba4323f3 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 @@ -41,11 +43,29 @@ #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); @@ -99,7 +119,7 @@ cga_out(uint16_t addr, uint8_t val, void *priv) uint8_t cga_in(uint16_t addr, void *priv) { - cga_t *cga = (cga_t *) priv; + const cga_t *cga = (cga_t *) priv; uint8_t ret = 0xff; @@ -135,7 +155,7 @@ cga_pravetz_out(UNUSED(uint16_t addr), uint8_t val, void *priv) uint8_t cga_pravetz_in(UNUSED(uint16_t addr), void *priv) { - cga_t *cga = (cga_t *) priv; + const cga_t *cga = (cga_t *) priv; return (cga->fontbase >> 8); } @@ -199,24 +219,275 @@ cga_recalctimings(cga_t *cga) cga->dispofftime = (uint64_t) (_dispofftime); } -void -cga_poll(void *priv) +static void +cga_render(cga_t *cga, int line) { - cga_t *cga = (cga_t *) priv; 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); @@ -231,141 +502,44 @@ cga_poll(void *priv) 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) { - border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); - - 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; @@ -382,7 +556,8 @@ cga_poll(void *priv) 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; } @@ -440,31 +615,45 @@ cga_poll(void *priv) 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); } } @@ -498,7 +687,8 @@ cga_poll(void *priv) } 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++) @@ -542,6 +732,15 @@ cga_standalone_init(UNUSED(const device_t *info)) 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; } @@ -621,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 }, { @@ -643,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 = "" } diff --git a/src/video/vid_cga_comp.c b/src/video/vid_cga_comp.c index 52e7675ee..d580f0c06 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,15 +229,15 @@ 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) { @@ -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; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 7b05098ef..a37eb38c7 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]; + 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, bg_col; - uint32_t dst_addr_backup, src_addr_backup; - uint32_t dst_addr, src_addr; - uint32_t sys_src32, sys_cnt; + 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 }; @@ -484,9 +523,9 @@ 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 @@ -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->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; + 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 = &((uint32_t *) svga->monitor->target_buffer->line[displine])[gd54xx->overlay.region1size + svga->x_add]; + p = &(svga->monitor->target_buffer->line[displine])[gd54xx->overlay.region1size + svga->x_add]; src2 += gd54xx->overlay.region1size * bytesperpix; OVERLAY_SAMPLE(); @@ -611,6 +650,23 @@ gd54xx_is_5434(svga_t *svga) return 0; } +static void +gd54xx_set_svga_fast(gd54xx_t *gd54xx) +{ + 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) { @@ -754,13 +810,14 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) break; case 0x07: svga->packed_chain4 = svga->seqregs[7] & 1; - svga_recalctimings(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; + gd54xx_set_svga_fast(gd54xx); + svga_recalctimings(svga); break; case 0x17: if (gd54xx_is_5422(svga)) @@ -768,6 +825,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) else return; break; + + default: + break; } return; } @@ -823,6 +883,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->dac_addr = (svga->dac_addr + 1) & 255; svga->dac_pos = 0; break; + + default: + break; } return; case 0x3ce: @@ -869,12 +932,13 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) 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 +969,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) } svga->seqregs[2] &= 0x0f; } + fallthrough; case 0x09: case 0x0a: gd54xx_recalc_banking(gd54xx); @@ -1024,6 +1089,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) case 0x39: gd543x_mmio_write(0xb8021, val, gd54xx); break; + + default: + break; } } return; @@ -1139,6 +1207,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->overlay.ena = (val & 1) != 0; gd54xx_update_overlay(gd54xx); break; + + default: + break; } if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { @@ -1152,6 +1223,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } svga_out(addr, val, svga); } @@ -1222,6 +1296,9 @@ gd54xx_in(uint16_t addr, void *priv) case 2048: ret |= 0x18; break; + + default: + break; } } break; @@ -1246,6 +1323,9 @@ gd54xx_in(uint16_t addr, void *priv) 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 +1341,9 @@ gd54xx_in(uint16_t addr, void *priv) case 4: ret |= 0x04; break; + + default: + break; } } break; @@ -1298,6 +1381,9 @@ gd54xx_in(uint16_t addr, void *priv) case 0x1e: ret = gd54xx->vclk_d[svga->seqaddr - 0x1b]; break; + + default: + break; } break; } else @@ -1353,6 +1439,9 @@ gd54xx_in(uint16_t addr, void *priv) else ret = svga->vgapal[index].b & 0x3f; break; + + default: + break; } break; case 0x3ce: @@ -1470,6 +1559,9 @@ gd54xx_in(uint16_t addr, void *priv) gd54xx->vportsync = !gd54xx->vportsync; ret = gd54xx->vportsync ? 0x80 : 0x00; break; + + default: + break; } } else { if ((svga->gdcaddr < 2) && !gd54xx->unlocked) @@ -1510,6 +1602,9 @@ gd54xx_in(uint16_t addr, void *priv) if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) ret = 0xff; /*Standard CL-GD5430/40*/ break; + + default: + break; } break; default: @@ -1557,7 +1652,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); @@ -1587,6 +1682,9 @@ 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)) { @@ -1608,9 +1706,11 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) } } 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,15 +1746,19 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) static void gd54xx_recalctimings(svga_t *svga) { - gd54xx_t *gd54xx = (gd54xx_t *) svga->priv; - 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->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 (linedbl) @@ -1785,8 +1889,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 +1919,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)) { 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 +1941,28 @@ gd54xx_recalctimings(svga_t *svga) } svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; + + 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; + } } static void gd54xx_hwcursor_draw(svga_t *svga, int displine) { - 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; + 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; @@ -1866,16 +1986,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 +2067,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_mem_sys_dest_read(gd54xx_t *gd54xx) +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, 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 +2129,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 @@ -1994,7 +2154,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *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); + gd54xx_mem_sys_src_write(gd54xx, val, 0); return; } @@ -2117,22 +2277,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; @@ -2165,11 +2321,11 @@ gd54xx_readb_linear(uint32_t addr, void *priv) /* 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 */ @@ -2189,8 +2345,9 @@ gd54xx_readb_linear(uint32_t addr, void *priv) static uint16_t gd54xx_readw_linear(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - 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; @@ -2209,18 +2366,19 @@ gd54xx_readw_linear(uint32_t addr, void *priv) /* 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, priv); - temp |= gd54xx_readb_linear(addr + 1, priv) << 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); @@ -2237,8 +2395,9 @@ gd54xx_readw_linear(uint32_t addr, void *priv) static uint32_t gd54xx_readl_linear(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - 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; @@ -2257,16 +2416,16 @@ gd54xx_readl_linear(uint32_t addr, void *priv) /* 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, priv); - temp |= gd54xx_readb_linear(addr + 1, priv) << 8; - temp |= gd54xx_readb_linear(addr + 2, priv) << 16; - temp |= gd54xx_readb_linear(addr + 3, priv) << 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,12 +2453,14 @@ gd54xx_readl_linear(uint32_t addr, void *priv) } static uint8_t -gd5436_aperture2_readb(uint32_t addr, void *priv) +gd5436_aperture2_readb(UNUSED(uint32_t addr), void *priv) { 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; } @@ -2310,7 +2471,8 @@ gd5436_aperture2_readw(uint32_t addr, void *priv) 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)) { + 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; @@ -2325,7 +2487,8 @@ gd5436_aperture2_readl(uint32_t addr, void *priv) 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)) { + 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; @@ -2337,13 +2500,14 @@ gd5436_aperture2_readl(uint32_t addr, void *priv) } static void -gd5436_aperture2_writeb(uint32_t addr, uint8_t val, void *priv) +gd5436_aperture2_writeb(UNUSED(uint32_t addr), uint8_t val, void *priv) { 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 @@ -2351,8 +2515,8 @@ gd5436_aperture2_writew(uint32_t addr, uint16_t val, void *priv) { 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); } @@ -2363,8 +2527,8 @@ gd5436_aperture2_writel(uint32_t addr, uint32_t val, void *priv) { 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); @@ -2378,7 +2542,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) 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) { svga_write_linear(addr, val, svga); @@ -2396,7 +2560,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) /* 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; } @@ -2422,10 +2586,10 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) static void gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - 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) { svga_writew_linear(addr, val, svga); @@ -2443,15 +2607,15 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) /* 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 +2626,24 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) 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; } @@ -2486,10 +2653,10 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) static void gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - 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) { svga_writel_linear(addr, val, svga); @@ -2507,17 +2674,17 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) /* 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 +2698,14 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) 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 +2722,7 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) 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; } @@ -2570,7 +2739,7 @@ gd54xx_read(uint32_t addr, void *priv) 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 = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); @@ -2788,6 +2957,9 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *priv) gd54xx_start_blit(0, 0xffffffff, gd54xx, svga); } break; + + default: + break; } } else if (gd54xx->mmio_vram_overlap) gd54xx_write(addr, val, gd54xx); @@ -2800,7 +2972,7 @@ gd543x_mmio_writeb(uint32_t addr, uint8_t val, void *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; } @@ -2982,11 +3154,14 @@ gd543x_mmio_read(uint32_t addr, void *priv) 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; @@ -3151,6 +3326,9 @@ gd54xx_get_pixel_width(gd54xx_t *gd54xx) case CIRRUS_BLTMODE_PIXELWIDTH32: ret = 4; break; + + default: + break; } return ret; @@ -3236,13 +3414,13 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) /* 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. */ @@ -3419,7 +3597,7 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) dst = svga->vram[dst_addr & svga->vram_mask]; svga->changedvram[(dst_addr & svga->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; @@ -3557,16 +3735,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 *priv) +cl_pci_read(UNUSED(int func), int addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - 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 +3792,7 @@ cl_pci_read(int func, int addr, void *priv) case 0x13: ret = gd54xx->lfb_base >> 24; if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - ret = 0xfe; + ret &= 0xfe; break; case 0x14: @@ -3650,17 +3827,20 @@ cl_pci_read(int func, int addr, void *priv) case 0x3d: ret = PCI_INTA; break; - } + + default: + break; + } return ret; } static void -cl_pci_write(int func, int addr, uint8_t val, void *priv) +cl_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - 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,13 +3900,16 @@ cl_pci_write(int func, int addr, uint8_t val, void *priv) case 0x3c: gd54xx->int_line = val; return; + + default: + break; } } static uint8_t gd5428_mca_read(int port, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; + const gd54xx_t *gd54xx = (gd54xx_t *) priv; return gd54xx->pos_regs[port & 7]; } @@ -3740,13 +3923,17 @@ gd5428_mca_write(int port, uint8_t val, void *priv) 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 *priv) { - return 1; + const gd54xx_t *gd54xx = (gd54xx_t *) priv; + + return gd54xx->pos_regs[2] & 0x01; } static void @@ -3768,7 +3955,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 +4008,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); @@ -3944,9 +4131,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 +4150,9 @@ static void case CIRRUS_ID_CLGD5480: romfn = BIOS_GD5480_PATH; break; + + default: + break; } if (info->flags & DEVICE_MCA) { @@ -4056,7 +4246,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 +4299,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); } @@ -4823,6 +5017,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", @@ -4837,6 +5045,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", diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index be176d9d0..dcc72a76b 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -135,8 +135,8 @@ colorplus_poll(void *priv) 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. */ diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index 4753ec223..430c7a64d 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -121,7 +121,7 @@ compaq_cga_poll(void *priv) 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; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 2f13a5c0e..670d88e61 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,15 +58,13 @@ 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 *priv); @@ -89,19 +89,12 @@ ega_out(uint16_t addr, uint8_t val, void *priv) 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 *priv) 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 *priv) 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 *priv) 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 *priv) 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,6 +261,9 @@ ega_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } } @@ -267,6 +287,7 @@ ega_in(uint16_t addr, void *priv) if (ati_eeprom_read((ati_eeprom_t *) ega->eeprom)) ret |= 8; break; + default: ret = ega->regs[ega->index]; break; @@ -292,6 +313,10 @@ ega_in(uint16_t addr, void *priv) if (ega_type) ret = ega->seqregs[ega->seqaddr & 0xf]; break; + case 0x3c6: + if (ega_type == 2) + ret = ega->ctl_mode; + break; case 0x3c8: if (ega_type) ret = 2; @@ -315,7 +340,7 @@ ega_in(uint16_t addr, void *priv) break; case 0x3d1: case 0x3d5: - switch(ega->crtcreg) { + switch (ega->crtcreg) { case 0xc: case 0xd: case 0xe: @@ -325,7 +350,7 @@ ega_in(uint16_t addr, void *priv) case 0x10: case 0x11: - // TODO: Return light pen address once implemented + /* TODO: Return light pen address once implemented. */ if (ega_type) ret = ega->crtc[ega->crtcreg]; break; @@ -333,12 +358,53 @@ ega_in(uint16_t addr, void *priv) default: if (ega_type) 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 +415,7 @@ void ega_recalctimings(ega_t *ega) { int clksel; + int color; double _dispontime; double _dispofftime; @@ -392,7 +459,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 +509,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,30 +525,43 @@ 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->y_add = (overscan_y >> 1); ega->x_add = (overscan_x >> 1); + if (ega->vres) + ega->y_add >>= 1; + if (ega->seqregs[1] & 8) { disptime = (double) ((ega->crtc[0] + 2) << 1); _dispontime = (double) ((ega->crtc[1] + 1) << 1); @@ -477,14 +580,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_dot_poll(void *priv) +{ + 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; + int x, y; int old_ma; int wx = 640; int wy = 350; @@ -504,37 +708,26 @@ ega_poll(void *priv) video_wait_for_buffer(); } - if (ega->vres) { - old_ma = ega->ma; - - ega->displine <<= 1; - ega->y_add <<= 1; - + 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->displine++; - - ega->ma = old_ma; - - 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->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 +739,18 @@ ega_poll(void *priv) 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 +762,11 @@ ega_poll(void *priv) 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 +777,23 @@ ega_poll(void *priv) 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,6 +801,7 @@ ega_poll(void *priv) else ega->ma = ega->maback = 0; ega->ma <<= 2; + ega->cca = ega->ma; ega->maback <<= 2; ega->sc = 0; if (ega->attrregs[0x10] & 0x20) { @@ -615,6 +829,9 @@ ega_poll(void *priv) 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 +871,19 @@ ega_poll(void *priv) 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 +900,12 @@ ega_poll(void *priv) 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 +992,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 +1011,9 @@ ega_remap_cpu_addr(uint32_t inaddr, ega_t *ega) case 0xC: // 32K B800 addr &= 0x7FFF; break; + + default: + break; } switch (a0mux) { @@ -811,15 +1027,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; } @@ -940,6 +1159,9 @@ ega_write(uint32_t addr, uint8_t val, void *priv) if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; break; + + default: + break; } } break; @@ -999,9 +1221,15 @@ ega_write(uint32_t addr, uint8_t val, void *priv) if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; break; + + default: + break; } } break; + + default: + break; } } @@ -1068,32 +1296,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 +1313,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 +1329,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 +1346,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 +1389,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 +1399,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 +1410,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 +1433,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 +1465,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 +1499,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 @@ -1311,11 +1536,11 @@ ega_speed_changed(void *priv) } /* 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). */ @@ -1435,15 +1660,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 01ee7ac04..98905e0c8 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -115,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; @@ -167,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; @@ -186,28 +194,28 @@ 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 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; 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; @@ -219,25 +227,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 e1290cd99..4f7dbae3e 100644 --- a/src/video/vid_et3000.c +++ b/src/video/vid_et3000.c @@ -246,7 +246,7 @@ et3000_init(const device_t *info) 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 b06283a1c..834de7513 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -52,6 +52,7 @@ #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_ISA 1 /* ISA ET4000AX */ @@ -366,8 +367,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; @@ -432,9 +433,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; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; case 6: case 7: et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; @@ -486,8 +485,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) uint32_t get_et4000_addr(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) priv; - uint32_t nbank; + const svga_t *svga = (svga_t *) priv; + uint32_t nbank; switch (svga->crtc[0x37] & 0x0B) { case 0x00: @@ -546,7 +545,7 @@ get_et4000_addr(uint32_t addr, void *priv) static void et4000_recalctimings(svga_t *svga) { - et4000_t *dev = (et4000_t *) svga->priv; + const et4000_t *dev = (et4000_t *) svga->priv; svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; if (svga->crtc[0x35] & 1) @@ -606,12 +605,20 @@ 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; + } } static void et4000_kasan_recalctimings(svga_t *svga) { - et4000_t *et4000 = (et4000_t *) svga->priv; + const et4000_t *et4000 = (et4000_t *) svga->priv; et4000_recalctimings(svga); @@ -627,7 +634,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]); } @@ -747,13 +754,16 @@ 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); 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; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index c2ce39778..b48135c37 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]; @@ -210,6 +210,9 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv) svga->gdcreg[svga->gdcaddr & 15] = val; et4000w32p_recalcmapping(et4000); return; + + default: + break; } break; case 0x3d4: @@ -290,6 +293,9 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv) case 8: svga->hwcursor.xoff += 32; break; + + default: + break; } } @@ -315,6 +321,9 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv) add2addr = svga->hwcursor.yoff * ((svga->hwcursor.cur_xsize == 128) ? 32 : 16); svga->hwcursor.addr += add2addr; return; + + default: + break; } svga_out(addr, val, svga); @@ -408,6 +417,9 @@ et4000w32p_in(uint16_t addr, void *priv) return (et4000->regs[0xef] & 0x8f) | (et4000->rev << 4) | et4000->vlb; } return et4000->regs[et4000->index]; + + default: + break; } return svga_in(addr, svga); @@ -452,6 +464,9 @@ et4000w32p_recalctimings(svga_t *svga) case 24: svga->clock /= 4; break; + + default: + break; } } } @@ -490,6 +505,9 @@ et4000w32p_recalctimings(svga_t *svga) break; svga->hdisp -= 24; break; + + default: + break; } } } @@ -500,7 +518,8 @@ 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; if (et4000->type <= ET4000W32P_REVC) { if (et4000->type == ET4000W32P_REVC) { if (svga->hdisp != 1024) @@ -513,10 +532,13 @@ et4000w32p_recalctimings(svga_t *svga) svga->hdisp /= 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; @@ -590,8 +612,14 @@ et4000w32p_recalctimings(svga_t *svga) else svga->render = svga_render_32bpp_highres; break; + + default: + break; } break; + + default: + break; } } } @@ -666,6 +694,9 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000) mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } } @@ -832,6 +863,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; } } @@ -967,9 +1001,15 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv) case 0x31: et4000->acl.osr = val; break; + + default: + break; } } break; + + default: + break; } } @@ -977,7 +1017,7 @@ static uint8_t et4000w32p_mmu_read(uint32_t addr, void *priv) { et4000w32p_t *et4000 = (et4000w32p_t *) priv; - svga_t *svga = &et4000->svga; + const svga_t *svga = &et4000->svga; uint8_t temp; switch (addr & 0x6000) { @@ -1072,8 +1112,7 @@ et4000w32p_mmu_read(uint32_t addr, void *priv) case 0x8e: if (et4000->type >= ET4000W32P_REVC) return et4000->acl.internal.pixel_depth; - else - return et4000->acl.internal.vbus; + return et4000->acl.internal.vbus; case 0x8f: return et4000->acl.internal.xy_dir; case 0x90: @@ -1104,9 +1143,15 @@ et4000w32p_mmu_read(uint32_t addr, void *priv) return et4000->acl.internal.dest_addr >> 16; case 0xa3: return et4000->acl.internal.dest_addr >> 24; + + default: + break; } return 0xff; + + default: + break; } return 0xff; @@ -2339,6 +2384,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) { @@ -2364,6 +2412,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)) { @@ -2451,16 +2502,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->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; + 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)) { @@ -2474,6 +2526,9 @@ et4000w32p_hwcursor_draw(svga_t *svga, int displine) minus_width = 64; x_acc = 2; break; + + default: + break; } } @@ -2559,7 +2614,7 @@ et4000w32p_io_set(et4000w32p_t *et4000) uint8_t et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) { - et4000w32p_t *et4000 = (et4000w32p_t *) priv; + const et4000w32p_t *et4000 = (et4000w32p_t *) priv; addr &= 0xff; @@ -2607,6 +2662,9 @@ et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) return 0x00; case 0x33: return et4000->pci_regs[0x33] & 0xf0; + + default: + break; } return 0; @@ -2658,6 +2716,9 @@ et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) mem_mapping_disable(&et4000->bios_rom.mapping); } return; + + default: + break; } } @@ -2790,6 +2851,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); @@ -2800,7 +2864,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 */ diff --git a/src/video/vid_f82c425.c b/src/video/vid_f82c425.c index a2ffeddb5..772926e1e 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 @@ -268,6 +268,9 @@ f82c425_out(uint16_t addr, uint8_t val, void *priv) f82c425_smartmap(f82c425); f82c425_colormap(f82c425); break; + + default: + break; } } @@ -300,6 +303,9 @@ f82c425_in(uint16_t addr, void *priv) return f82c425->timing; case 0xdf: return f82c425->function; + + default: + break; } return 0xff; @@ -317,7 +323,8 @@ f82c425_write(uint32_t addr, uint8_t val, void *priv) static uint8_t f82c425_read(uint32_t addr, void *priv) { - f82c425_t *f82c425 = (f82c425_t *) priv; + const f82c425_t *f82c425 = (f82c425_t *) priv; + cycles -= 4; return f82c425->vram[addr & 0x3fff]; @@ -391,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]; } } @@ -420,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; } @@ -447,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; } @@ -506,6 +513,9 @@ f82c425_poll(void *priv) case 0x01: f82c425_text_row(f82c425); break; + + default: + break; } } f82c425->displine++; diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 763cfe540..4ae8e6fd1 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. @@ -204,14 +204,17 @@ genius_out(uint16_t addr, uint8_t val, void *priv) case 0x3d9: genius->cga_colour = val; return; + + default: + break; } } uint8_t genius_in(uint16_t addr, void *priv) { - genius_t *genius = (genius_t *) priv; - 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 *priv) case 0x3da: ret = genius->cga_stat; break; + + default: + break; } return ret; @@ -295,8 +301,9 @@ genius_write(uint32_t addr, uint8_t val, void *priv) uint8_t genius_read(uint32_t addr, void *priv) { - genius_t *genius = (genius_t *) priv; - 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); @@ -721,9 +734,8 @@ genius_poll(void *priv) } } -void - * - genius_init(const device_t *info) +void * +genius_init(UNUSED(const device_t *info)) { genius_t *genius = malloc(sizeof(genius_t)); diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index e2879cec3..2a725488d 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -152,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: diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 587410c07..429632f19 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -139,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*/ @@ -172,8 +173,8 @@ herculesplus_out(uint16_t port, uint8_t val, void *priv) 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: @@ -214,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]; } @@ -230,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; @@ -282,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; @@ -299,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; } } @@ -342,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; } } @@ -445,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; @@ -521,6 +489,7 @@ herculesplus_poll(void *priv) int x; int oldvc; int oldsc; + int cw = HERCULESPLUS_CW; VIDEO_MONITOR_PROLOGUE(); if (!dev->linepos) { @@ -544,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); } @@ -607,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; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 2c44c8b28..9cd68e4ee 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -35,6 +35,7 @@ #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 { @@ -135,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]; @@ -320,9 +321,7 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) svga->adv_flags &= ~FLAG_RAMDAC_SHIFT; if (val & 0x04) svga->adv_flags |= FLAG_RAMDAC_SHIFT; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; /*Bank registers*/ case 0xe8: case 0xe9: @@ -383,6 +382,9 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) svga->fullchange = changeframecount; svga_recalctimings(svga); break; + + default: + break; } return; } @@ -460,6 +462,9 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) ht216_remap(ht216); } break; + + default: + break; } svga_out(addr, val, svga); @@ -528,6 +533,9 @@ ht216_in(uint16_t addr, void *priv) ret = svga->latch.b[ht216->bg_plane_sel]; ht216->bg_plane_sel = 0; break; + + default: + break; } return ret; @@ -558,6 +566,9 @@ ht216_in(uint16_t addr, void *priv) if (svga->crtcreg == 0x1f) return svga->crtc[0xc] ^ 0xea; return svga->crtc[svga->crtcreg]; + + default: + break; } return svga_in(addr, svga); @@ -705,11 +716,11 @@ ht216_recalctimings(svga_t *svga) static void ht216_hwcursor_draw(svga_t *svga, int displine) { - 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); + 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; @@ -722,9 +733,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; @@ -860,6 +871,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) { @@ -921,6 +935,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) { @@ -968,6 +985,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) @@ -1018,6 +1038,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); @@ -1105,10 +1128,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; @@ -1129,6 +1152,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: @@ -1141,6 +1167,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*/ @@ -1377,9 +1406,9 @@ ht216_read_common(ht216_t *ht216, uint32_t addr) static uint8_t ht216_read(uint32_t addr, void *priv) { - ht216_t *ht216 = (ht216_t *) priv; - 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]; @@ -1395,8 +1424,8 @@ ht216_read(uint32_t addr, void *priv) static uint8_t ht216_read_linear(uint32_t addr, void *priv) { - ht216_t *ht216 = (ht216_t *) priv; - 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*/ @@ -1409,8 +1438,10 @@ ht216_read_linear(uint32_t addr, void *priv) 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]); } @@ -1505,6 +1536,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; diff --git a/src/video/vid_ibm_rgb528_ramdac.c b/src/video/vid_ibm_rgb528_ramdac.c index b7a27781b..1b19a3a0f 100644 --- a/src/video/vid_ibm_rgb528_ramdac.c +++ b/src/video/vid_ibm_rgb528_ramdac.c @@ -27,32 +27,41 @@ #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]; @@ -60,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; @@ -155,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; @@ -224,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; @@ -349,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; @@ -438,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; @@ -551,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; @@ -612,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; @@ -712,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); @@ -781,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; @@ -814,6 +836,9 @@ ibm_rgb528_recalctimings(void *p, svga_t *svga) case 32: svga->render = ibm_rgb528_render_32bpp; break; + + default: + break; } } } @@ -824,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 @@ -873,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: @@ -889,6 +917,9 @@ ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) /* Complement */ p[x_pos] ^= 0xffffff; break; + + default: + break; } break; case 0x03: @@ -901,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) diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index adfaf6ad4..4c23d6ec5 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -34,9 +34,12 @@ 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 @@ -58,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; @@ -138,7 +141,7 @@ icd2061_write(void *p, int val) float icd2061_getclock(int clock, void *priv) { - icd2061_t *icd2061 = (icd2061_t *) priv; + const icd2061_t *icd2061 = (icd2061_t *) priv; if (clock > 2) clock = 2; diff --git a/src/video/vid_ics2494.c b/src/video/vid_ics2494.c index 16c4139fe..309d07966 100644 --- a/src/video/vid_ics2494.c +++ b/src/video/vid_ics2494.c @@ -51,7 +51,7 @@ ics2494_log(const char *fmt, ...) float ics2494_getclock(int clock, void *priv) { - ics2494_t *ics2494 = (ics2494_t *) priv; + 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 6420ee7e4..ecb414f2b 100644 --- a/src/video/vid_ics2595.c +++ b/src/video/vid_ics2595.c @@ -26,9 +26,11 @@ #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; @@ -43,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; @@ -88,6 +90,7 @@ static void * ics2595_init(UNUSED(const device_t *info)) { ics2595_t *ics2595 = (ics2595_t *) malloc(sizeof(ics2595_t)); + memset(ics2595, 0, sizeof(ics2595_t)); return ics2595; @@ -105,15 +108,15 @@ ics2595_close(void *priv) double ics2595_getclock(void *priv) { - ics2595_t *ics2595 = (ics2595_t *) priv; + 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 25ba92e9c..c7602ffd0 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -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; @@ -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 7a3b416fc..e3f37ec65 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -252,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; } } @@ -354,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 */ @@ -749,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; @@ -769,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; @@ -850,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); @@ -931,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; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 8888208e2..a53199324 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -75,7 +75,7 @@ mda_out(uint16_t addr, uint8_t val, void *priv) uint8_t mda_in(uint16_t addr, void *priv) { - mda_t *mda = (mda_t *) priv; + const mda_t *mda = (mda_t *) priv; switch (addr) { case 0x3b0: @@ -107,7 +107,7 @@ mda_write(uint32_t addr, uint8_t val, void *priv) uint8_t mda_read(uint32_t addr, void *priv) { - mda_t *mda = (mda_t *) priv; + const mda_t *mda = (mda_t *) priv; return mda->vram[addr & 0xfff]; } @@ -165,9 +165,9 @@ mda_poll(void *priv) 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]; } diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f9387987b..ccbf1c1b3 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 @@ -234,6 +253,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 +328,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 +370,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 +407,8 @@ enum { MGA_2064W, /*Millennium*/ MGA_1064SG, /*Mystique*/ MGA_1164SG, /*Mystique 220*/ + MGA_2164W, /*Millennium II*/ + MGA_G100, /*Productiva G100*/ }; enum { @@ -424,12 +451,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 +466,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; @@ -478,11 +508,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 +539,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 +658,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 }; @@ -664,13 +707,11 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x3c8: mystique->xreg_idx = val; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + 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; } @@ -716,32 +757,65 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) 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); - } - if (mystique->crtcext_idx == 4) { - if (svga->gdcreg[6] & 0xc) { - /*64k banks*/ - 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; + 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*/ + 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*/ + 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; + } + } + } + break; + + default: break; } @@ -770,7 +844,7 @@ mystique_in(uint16_t addr, void *priv) 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); @@ -814,6 +888,18 @@ 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) { @@ -828,7 +914,7 @@ mystique_vsync_callback(svga_t *svga) static float mystique_getclock(int clock, void *priv) { - mystique_t *mystique = (mystique_t *) priv; + const mystique_t *mystique = (mystique_t *) priv; if (clock == 0) return 25175000.0; @@ -854,78 +940,115 @@ mystique_recalctimings(svga_t *svga) 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; 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)) { + + 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) { @@ -946,13 +1069,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 @@ -978,7 +1114,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); @@ -990,7 +1126,7 @@ 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); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0x1ffff; break; case 0x4: /*64k at A0000*/ @@ -1005,6 +1141,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*/ @@ -1022,18 +1161,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) \ @@ -1258,6 +1399,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: @@ -1370,12 +1513,12 @@ mystique_ctrl_read_b(uint32_t addr, void *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; @@ -1423,13 +1566,16 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) 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: @@ -1437,7 +1583,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) break; case REG_IEN: - ret = mystique->ien & 0x64; + ret = mystique->ien & 0x65; break; case REG_IEN + 1: case REG_IEN + 2: @@ -1606,6 +1752,10 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) 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: @@ -1742,7 +1892,7 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) 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: @@ -1933,12 +2083,12 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) { 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; @@ -1980,6 +2130,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) switch (addr & 0x3fff) { case REG_ICLEAR: if (val & ICLEAR_SOFTRAPICLR) { + //pclog("softrapiclr\n"); mystique->status &= ~STATUS_SOFTRAPEN; mystique_update_irqs(mystique); } @@ -2024,6 +2175,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); WRITE8(addr, mystique->dma.primaddress, val); mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; thread_release_mutex(mystique->dma.lock); break; @@ -2057,6 +2209,12 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) 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: @@ -2214,7 +2372,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) 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: @@ -2276,7 +2434,9 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) 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); } @@ -2289,7 +2449,9 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) 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; @@ -2302,7 +2464,9 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) 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; @@ -2335,14 +2499,47 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) 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; @@ -2380,9 +2577,47 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) 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: @@ -2419,14 +2654,25 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) 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; @@ -2550,9 +2796,15 @@ mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) priv; + const svga_t *svga = (svga_t *) priv; + mystique_t *mystique = (mystique_t *) svga->priv; - cycles -= video_timing_read_b; + if (mystique->type < MGA_1064SG) { + if (!svga->fast) + return svga_read_linear(addr, priv); + } + + cycles -= svga->monitor->mon_video_timing_read_b; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2566,7 +2818,7 @@ mystique_readw_linear(uint32_t addr, void *priv) { 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) @@ -2580,7 +2832,7 @@ mystique_readl_linear(uint32_t addr, void *priv) { 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) @@ -2593,14 +2845,22 @@ static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; + mystique_t *mystique = (mystique_t *) svga->priv; - cycles -= video_timing_write_b; + if (mystique->type < MGA_1064SG) { + if (!svga->fast) { + svga_write_linear(addr, val, priv); + return; + } + } + + cycles -= svga->monitor->mon_video_timing_write_b; 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; } @@ -2609,13 +2869,13 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) { 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; } @@ -2624,13 +2884,13 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) { 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; } @@ -2641,27 +2901,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.pri_header & 0xff) != 0x15) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + break; + } + + { 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) @@ -2672,15 +2957,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; @@ -2695,9 +2989,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; @@ -2716,23 +3037,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; @@ -2741,12 +3079,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; @@ -2755,6 +3098,9 @@ run_dma(mystique_t *mystique) fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); } break; + + default: + break; } } @@ -2787,6 +3133,9 @@ fifo_thread(void *priv) 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; @@ -2859,12 +3208,14 @@ mystique_softrap_pending_timer(void *priv) 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 @@ -2923,6 +3274,9 @@ bitop(uint32_t src, uint32_t dst, uint32_t dwgctrl) return dst | src; case BOP(0xf): return ~0; + + default: + break; } return 0; @@ -3839,10 +4193,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: @@ -3917,21 +4271,45 @@ 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) { svga_t *svga = &mystique->svga; - uint32_t src; + uint32_t src = 0; uint32_t dst; uint32_t old_dst; int x; + int len = 0; 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 (len <= mystique->dwgreg.length) { 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: @@ -3939,8 +4317,13 @@ 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 && (len < mystique->dwgreg.length)) { + 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: @@ -3948,17 +4331,27 @@ 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 && (len < mystique->dwgreg.length)) { + ((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 && (len < mystique->dwgreg.length)) { + *(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: @@ -3966,8 +4359,13 @@ 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 && (len < mystique->dwgreg.length)) { + ((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: @@ -3989,7 +4387,7 @@ blit_line(mystique_t *mystique, int closed) } else mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.length--; + len++; } break; @@ -3999,18 +4397,30 @@ blit_line(mystique_t *mystique, int closed) 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))) @@ -4036,7 +4446,13 @@ 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]; @@ -4049,7 +4465,13 @@ blit_line(mystique_t *mystique, int closed) else x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + 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]; @@ -4061,7 +4483,9 @@ blit_line(mystique_t *mystique, int closed) 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; } @@ -4107,6 +4531,7 @@ 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; @@ -4115,8 +4540,6 @@ blit_trap(mystique_t *mystique) int y; 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: @@ -4158,25 +4581,24 @@ blit_trap(mystique_t *mystique) fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - x_l++; - mystique->pixel_count++; + if (x_l > x_r) + x_l--; + else + x_l++; + } - 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 ((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); + } + mystique->dwgreg.ar[1] += 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 ((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); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4238,25 +4660,23 @@ blit_trap(mystique_t *mystique) fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - x_l++; - mystique->pixel_count++; + if (x_l > x_r) + x_l--; + else + x_l++; } - 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 ((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); + } + mystique->dwgreg.ar[1] += 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 ((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); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4272,12 +4692,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]; @@ -4285,10 +4707,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; @@ -4302,8 +4732,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: @@ -4334,16 +4769,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]; @@ -4361,7 +4810,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]; @@ -4375,41 +4830,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; + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + svga_t* svga = &mystique->svga; + uint16_t src = 0x0; - 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); + int atransp_dummy = 0; - 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; - - 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) @@ -4429,7 +4870,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 @@ -4440,14 +4881,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; @@ -4456,8 +4897,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; @@ -4467,6 +4922,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); } @@ -4480,8 +5040,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: @@ -4489,12 +5047,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]; @@ -4502,21 +5062,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; @@ -4525,7 +5099,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: @@ -4575,6 +5185,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; @@ -4582,30 +5212,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]; @@ -4620,13 +5277,23 @@ skip_pixel: 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; @@ -4658,6 +5325,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++) { @@ -4666,7 +5334,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) { @@ -4719,9 +5387,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; } @@ -4759,6 +5432,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"); @@ -4770,7 +5444,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; @@ -4826,9 +5500,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; } @@ -4909,9 +5588,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; } @@ -4936,7 +5620,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; } @@ -4950,7 +5636,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: @@ -4962,7 +5650,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; @@ -4990,7 +5680,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: @@ -5162,9 +5854,9 @@ mystique_start_blit(mystique_t *mystique) static void mystique_hwcursor_draw(svga_t *svga, int displine) { - mystique_t *mystique = (mystique_t *) svga->priv; - 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; @@ -5176,7 +5868,7 @@ 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] = (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; @@ -5185,18 +5877,51 @@ mystique_hwcursor_draw(svga_t *svga, int displine) dat[1] <<= 1; } break; + + default: + break; } if (svga->interlace && !svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; } +static uint8_t +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 *) 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 (mystique->type >= MGA_1164SG) + { + /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ + if (addr >= 0x10 && addr <= 0x13) + addr += 0x4; + else if (addr >= 0x14 && addr <= 0x17) + addr -= 0x4; + } + if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40)) ret = 0x00; else @@ -5209,10 +5934,16 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) 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: @@ -5230,7 +5961,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) break; /*Fast DEVSEL timing*/ case 0x08: - ret = 0; + ret = (mystique->type == MGA_1164SG) ? 3 : 0; break; /*Revision ID*/ case 0x09: ret = 0; @@ -5260,7 +5991,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) ret = 0x00; break; /*Linear frame buffer*/ case 0x16: - ret = (mystique->lfb_base >> 16) & 0x80; + ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80); break; case 0x17: ret = mystique->lfb_base >> 24; @@ -5301,6 +6032,10 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0x33: ret = mystique->pci_regs[0x33]; break; + + case 0x34: + ret = mystique->type == MGA_G100 ? 0xdc : 0x00; + break; case 0x3c: ret = mystique->int_line; @@ -5336,6 +6071,62 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) 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; @@ -5346,6 +6137,15 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; + if (mystique->type >= MGA_1164SG) + { + /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ + if (addr >= 0x10 && addr <= 0x13) + addr += 0x4; + else if (addr >= 0x14 && addr <= 0x17) + addr -= 0x4; + } + switch (addr) { case PCI_REG_COMMAND: mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80; @@ -5374,11 +6174,13 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x16: + if (mystique->type >= MGA_2164W) + break; 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->lfb_base = (mystique->lfb_base & ((mystique->type >= MGA_2164W) ? 0x00000000 : 0x00800000)) | (val << 24); mystique_recalc_mapping(mystique); break; @@ -5397,9 +6199,11 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) 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); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); return; @@ -5423,11 +6227,11 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) 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); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (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; @@ -5450,17 +6254,66 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) 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)); @@ -5468,12 +6321,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"); @@ -5483,8 +6343,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, @@ -5494,6 +6354,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->vram_size >= 16) + mystique->svga.decode_mask = mystique->svga.vram_mask; + 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, @@ -5503,6 +6367,8 @@ mystique_init(const device_t *info) NULL); mystique->svga.clock_gen = mystique; mystique->svga.getclock = mystique_getclock; + if (mystique->vram_size >= 16) + mystique->svga.decode_mask = mystique->svga.vram_mask; } io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); @@ -5515,7 +6381,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, @@ -5524,7 +6390,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]; @@ -5572,9 +6441,14 @@ mystique_init(const device_t *info) timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *) mystique, 1); 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)); @@ -5621,6 +6495,18 @@ 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 *priv) { @@ -5669,6 +6555,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", @@ -5710,3 +6628,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_oak_oti.c b/src/video/vid_oak_oti.c index 932e13913..f5bc449e6 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -38,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 { @@ -84,8 +84,9 @@ oti_out(uint16_t addr, uint8_t val, void *priv) if (!oti->chip_id) { oti->enable_register = val & 1; return; - } else - break; + } + svga_out(addr, val, svga); + return; case 0x3c6: case 0x3c7: @@ -156,8 +157,8 @@ oti_out(uint16_t addr, uint8_t val, void *priv) 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,8 +192,14 @@ oti_out(uint16_t addr, uint8_t val, void *priv) svga->read_bank = (val & 0xf) * 65536; svga->write_bank = (val >> 4) * 65536; break; + + default: + break; } return; + + default: + break; } svga_out(addr, val, svga); @@ -290,6 +297,9 @@ oti_in(uint16_t addr, void *priv) if (svga->attrregs[0x11] & 0x80) svga->cgastat |= 0x20; break; + + default: + break; } temp = svga->cgastat; break; @@ -338,7 +348,7 @@ oti_pos_out(UNUSED(uint16_t addr), uint8_t val, void *priv) static uint8_t oti_pos_in(UNUSED(uint16_t addr), void *priv) { - oti_t *oti = (oti_t *) priv; + 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->priv; - 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) { diff --git a/src/video/vid_ogc.c b/src/video/vid_ogc.c index edc4c841e..c3073898d 100644 --- a/src/video/vid_ogc.c +++ b/src/video/vid_ogc.c @@ -84,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: @@ -102,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; } } @@ -110,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; @@ -133,8 +138,11 @@ ogc_in(uint16_t addr, void *priv) ret = ret | 0xe0; if (ogc->mono_display) ret = ret | 0x10; - break; } + break; + + default: + break; } return ret; @@ -513,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 */ @@ -575,7 +583,9 @@ ogc_mdaattr_rebuild(void) void * 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)); @@ -583,8 +593,10 @@ ogc_init(UNUSED(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 a00015f9e..ad197f302 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -119,6 +119,9 @@ paradise_in(uint16_t addr, void *priv) case 0x0f: return (svga->gdcreg[0x0f] & 0x17) | 0x80; + + default: + break; } break; @@ -130,6 +133,9 @@ paradise_in(uint16_t addr, void *priv) 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); } @@ -198,6 +204,9 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } } svga->gdcreg[6] = val; @@ -213,6 +222,9 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) svga->gdcreg[0x0b] = val; paradise_remap(paradise); return; + + default: + break; } break; @@ -254,6 +266,9 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) mem_mapping_enable(¶dise->svga.mapping); } break; + + default: + break; } svga_out(addr, val, svga); @@ -262,7 +277,8 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) void paradise_remap(paradise_t *paradise) { - svga_t *svga = ¶dise->svga; + const svga_t *svga = ¶dise->svga; + paradise->check = 0; if (svga->seqregs[0x11] & 0x80) { @@ -301,7 +317,7 @@ paradise_remap(paradise_t *paradise) void paradise_recalctimings(svga_t *svga) { - paradise_t *paradise = (paradise_t *) svga->priv; + const paradise_t *paradise = (paradise_t *) svga->priv; svga->lowres = !(svga->gdcreg[0x0e] & 0x01); @@ -325,23 +341,44 @@ paradise_recalctimings(svga_t *svga) } } + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + svga->interlace = 0; + } + if (paradise->type < WD90C30) { - if (svga->bpp >= 8 && !svga->lowres) { + if ((svga->bpp >= 8) && !svga->lowres) { svga->render = svga_render_8bpp_highres; } } else { - if (svga->bpp >= 8 && !svga->lowres) { + if ((svga->bpp >= 8) && !svga->lowres) { 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; } } } + + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->hdisp == 360) + svga->hdisp <<= 1; + if (svga->seqregs[1] & 8) { + svga->render = svga_render_text_40; + } else + svga->render = svga_render_text_80; + } } static void @@ -583,6 +620,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); @@ -607,6 +647,9 @@ paradise_init(const device_t *info, uint32_t memsize) svga->crtc[0x36] = '3'; svga->crtc[0x37] = '0'; break; + + default: + break; } svga->bpp = 8; diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 0033e96d1..aa1517ddf 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -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. @@ -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). @@ -2196,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; } } @@ -2203,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 */ @@ -2233,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); @@ -2296,6 +2302,9 @@ pgc_write(uint32_t addr, uint8_t val, void *priv) case 0x3ff: /* reboot the PGC */ pgc_wake(dev); break; + + default: + break; } } } @@ -2310,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; @@ -2328,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; @@ -2384,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; @@ -2427,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; diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index f643fd1e4..eef95a910 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -106,6 +106,9 @@ rtg_in(uint16_t addr, void *priv) case 0x3d7: return dev->bank3d7; + + default: + break; } return svga_in(addr, svga); @@ -140,6 +143,9 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) case 0x0f: rtg_recalcbanking(dev); return; + + default: + break; } } break; @@ -163,6 +169,9 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) svga->fullchange = changeframecount; svga_recalctimings(svga); break; + + default: + break; } } @@ -188,6 +197,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); @@ -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,6 +253,9 @@ rtg_recalctimings(svga_t *svga) case 3: svga->clock /= 4; break; + + default: + break; } if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { @@ -281,6 +299,9 @@ rtg_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; } break; + + default: + break; } } } @@ -307,6 +328,9 @@ rtg_init(const device_t *info) io_sethandler(0x03c0, 32, rtg_in, NULL, NULL, rtg_out, NULL, NULL, dev); break; + + default: + break; } dev->svga.bpp = 8; @@ -314,7 +338,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; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index d242f907a..f9d49b79f 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> @@ -62,6 +64,7 @@ #define ROM_DIAMOND_STEALTH64_764 "roms/video/s3/stealt64.bin" #define ROM_TRIO64V2_DX_VBE20 "roms/video/s3/86c775_2.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" @@ -93,6 +96,7 @@ enum { S3_TRIO64V2_DX_ONBOARD, S3_PHOENIX_TRIO64VPLUS, S3_PHOENIX_TRIO64VPLUS_ONBOARD, + S3_CARDEX_TRIO64VPLUS, S3_DIAMOND_STEALTH_SE, S3_DIAMOND_STEALTH_VRAM, S3_ELSAWIN2KPROX_964, @@ -147,6 +151,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, @@ -210,7 +215,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; @@ -222,14 +229,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; @@ -245,10 +252,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; @@ -261,10 +268,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; @@ -362,6 +380,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) @@ -396,6 +416,24 @@ 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.*/ static __inline uint32_t @@ -466,13 +504,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); @@ -493,7 +531,7 @@ 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]; @@ -503,7 +541,7 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); 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 \ @@ -550,7 +588,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. */ @@ -561,23 +599,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: @@ -585,11 +636,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: @@ -598,21 +692,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: @@ -621,12 +715,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; } } } @@ -641,15 +738,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: @@ -657,15 +754,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: @@ -673,11 +770,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) { @@ -685,14 +782,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; } } } @@ -700,20 +800,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: @@ -729,16 +826,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; @@ -811,7 +905,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: @@ -821,7 +915,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: @@ -831,8 +925,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: @@ -841,8 +933,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: @@ -855,8 +945,11 @@ 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); + if (s3->bpp == 3) { + if (!(s3->accel.multifunc[0xe] & 0x200) && !(svga->crtc[0x32] & 0x40)) + s3->accel.multifunc[0xe] &= ~0x10; + } break; case 0x994a: @@ -877,15 +970,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); @@ -898,202 +984,182 @@ 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)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16); else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val; break; case 0xa149: case 0xa2e9: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24); else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (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) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val; + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16); break; case 0xa14b: case 0xa2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - 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->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xa548: case 0xa6e8: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16); else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val; break; case 0xa549: case 0xa6e9: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24); else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (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: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val; + else + s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16); break; case 0xa54b: case 0xa6eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - 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->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8); + else + s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xa948: case 0xaae8: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16); else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val; break; case 0xa949: case 0xaae9: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24); else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (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: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val; + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16); break; case 0xa94b: case 0xaaeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - 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->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xad48: case 0xaee8: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16); else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val; break; case 0xad49: case 0xaee9: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24); else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xad4a: case 0xaeea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val; + else + s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16); break; case 0xad4b: case 0xaeeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8); + else + s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xb148: case 0xb2e8: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16); else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val; break; case 0xb149: case 0xb2e9: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24); else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xb14a: case 0xb2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val; + else + s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16); break; case 0xb14b: case 0xb2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8); + else + s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xb548: @@ -1126,42 +1192,35 @@ 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)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16); else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val; break; case 0xe549: case 0xe6e9: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24); else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xe54a: case 0xe6ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - 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; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val; + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16); break; case 0xe54b: case 0xe6eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xe948: case 0xeae8: @@ -1181,42 +1240,35 @@ 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)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16); else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val; break; case 0xed49: case 0xeee9: - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24); else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xed4a: case 0xeeea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - 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; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val; + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16); break; case 0xed4b: case 0xeeeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - 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); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xe148: @@ -1230,16 +1282,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; @@ -1250,68 +1341,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); + 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); - } + 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)); - } 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); - } + 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: @@ -1330,65 +1429,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; } } @@ -1406,15 +1502,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); @@ -1429,11 +1518,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); } @@ -1441,7 +1529,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; @@ -1592,6 +1680,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; } @@ -1601,11 +1692,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) { @@ -1682,7 +1773,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 @@ -1695,19 +1786,19 @@ mmio_byte_write: 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); } } } @@ -1717,15 +1808,15 @@ mmio_byte_write: 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; @@ -1958,7 +2049,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); @@ -2004,16 +2095,16 @@ s3_hwcursor_convert_addr(svga_t *svga) static void s3_hwcursor_draw(svga_t *svga, int displine) { - 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; + 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: @@ -2033,7 +2124,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; @@ -2047,8 +2138,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: @@ -2333,17 +2429,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->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]; + 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]); @@ -2450,7 +2546,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; @@ -2505,7 +2601,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); @@ -2568,7 +2664,6 @@ s3_out(uint16_t addr, uint8_t val, void *priv) s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; uint8_t old; - uint8_t mask; int rs2; int rs3; @@ -2593,6 +2688,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x13: svga_recalctimings(svga); return; + + default: + break; } } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ @@ -2625,26 +2723,21 @@ s3_out(uint16_t addr, uint8_t val, void *priv) 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); @@ -2681,41 +2774,12 @@ s3_out(uint16_t addr, uint8_t val, void *priv) 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; break; @@ -2799,6 +2863,8 @@ s3_out(uint16_t addr, uint8_t val, void *priv) 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: @@ -2812,6 +2878,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) 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; @@ -2826,6 +2895,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) 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; @@ -2839,7 +2911,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) 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 { @@ -2858,6 +2930,21 @@ s3_out(uint16_t addr, uint8_t val, void *priv) 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); @@ -2890,6 +2977,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } if (old != val) { if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { @@ -2905,6 +2995,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } svga_out(addr, val, svga); } @@ -2937,7 +3030,8 @@ s3_in(uint16_t addr, void *priv) 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_PHOENIX_TRIO64VPLUS_ONBOARD) || + (s3->card_type == S3_CARDEX_TRIO64VPLUS)) && (svga->seqaddr == 0x17)) svga->seqregs[svga->seqaddr] ^= 0x01; return temp; } @@ -2951,16 +3045,21 @@ s3_in(uint16_t addr, void *priv) 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); @@ -2968,7 +3067,6 @@ s3_in(uint16_t addr, void *priv) return sc1502x_ramdac_in(addr, svga->ramdac, svga); else return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); - break; case 0x3d4: return svga->crtcreg; @@ -2978,8 +3076,15 @@ s3_in(uint16_t addr, void *priv) 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: @@ -2988,7 +3093,7 @@ s3_in(uint16_t addr, void *priv) 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 */ @@ -3019,6 +3124,7 @@ s3_in(uint16_t addr, void *priv) } } else return svga->crtc[0x6b]; + break; case 0x6c: if (s3->chip != S3_TRIO64V2) { if (svga->crtc[0x53] & 0x08) { @@ -3027,8 +3133,15 @@ s3_in(uint16_t addr, void *priv) return (svga->crtc[0x5a] & 0x80); } else return svga->crtc[0x6c]; + break; + + default: + break; } return svga->crtc[svga->crtcreg]; + + default: + break; } return svga_in(addr, svga); } @@ -3038,14 +3151,7 @@ s3_recalctimings(svga_t *svga) { 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; - } - } - } + uint8_t mask = 0xc0; svga->ma_latch |= (s3->ma_ext << 16); if (s3->chip >= S3_86C928) { @@ -3055,7 +3161,7 @@ s3_recalctimings(svga_t *svga) 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->seqregs[1] & 8) ? 16 : 8)); } if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; @@ -3063,6 +3169,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) @@ -3080,17 +3188,19 @@ s3_recalctimings(svga_t *svga) 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 +3211,48 @@ s3_recalctimings(svga_t *svga) case 7: svga->clock /= 2; break; + + default: + break; } - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + 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; + } + +#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) { @@ -3130,24 +3273,100 @@ s3_recalctimings(svga_t *svga) s3->width = 1024; } } +#endif - if ((svga->crtc[0x43] & 0x08) && !s3->color_16bit && (s3->chip <= S3_86C805)) { - s3->color_16bit = 1; - s3->width = 1024; - } else if (!(svga->crtc[0x43] & 0x08) && s3->color_16bit && (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)) { + 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; + break; + case 2048: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + break; + case 640: + svga->hdisp <<= 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; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION964: + switch (s3->card_type) { + case S3_ELSAWIN2KPROX_964: + svga->hdisp <<= 1; + break; + + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_NUMBER9_9FX_771: + case S3_SPEA_MERCURY_P64V: + case S3_ELSAWIN2KPROX: + case S3_PHOENIX_VISION968: + svga->hdisp <<= 1; + break; + case S3_MIROVIDEO40SV_ERGO_968: + switch (s3->width) { + case 1152: + case 1280: + svga->hdisp <<= 1; + break; + 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) { @@ -3167,52 +3386,161 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; } else if (s3->card_type == S3_NUMBER9_9FX_771) svga->hdisp <<= 1; - - 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 768: - svga->hdisp = 1024; - break; - - case 864: - svga->hdisp = 1152; - break; - - case 1024: - if (svga->vtotal == 1066) - svga->hdisp = 1280; - 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; - } } +#endif break; case 15: svga->render = svga_render_15bpp_highres; + switch (s3->chip) { + case S3_86C911: + case S3_86C924: + svga->hdisp >>= 1; + break; + + case S3_86C801: + switch (s3->card_type) { + case S3_PHOENIX_86C801: + svga->hdisp >>= 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; + 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; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928: + switch (s3->card_type) { + case S3_METHEUS_86C928: + if (!s3->color_16bit) + svga->hdisp <<= 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; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION864: + switch (s3->card_type) { + case S3_MIROCRYSTAL20SD_864: + svga->hdisp >>= 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; + 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; + break; + + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + svga->hdisp <<= 1; + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + + case S3_ELSAWIN2KPROX: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + + case S3_TRIO64: + case S3_TRIO32: + svga->hdisp >>= 1; + break; + + default: + break; + } +#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 +3562,160 @@ 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; + break; + + case S3_86C801: + switch (s3->card_type) { + case S3_PHOENIX_86C801: + svga->hdisp >>= 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; + 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; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_86C928: + switch (s3->card_type) { + case S3_METHEUS_86C928: + svga->hdisp <<= 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; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION864: + switch (s3->card_type) { + case S3_MIROCRYSTAL20SD_864: + svga->hdisp >>= 1; + break; + + default: + break; + } + break; + case S3_VISION868: + switch (s3->card_type) { + case S3_PHOENIX_VISION868: + case S3_NUMBER9_9FX_531: + svga->hdisp >>= 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; + break; + default: + break; + } + break; + + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + svga->hdisp <<= 1; + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + + case S3_ELSAWIN2KPROX: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + + case S3_TRIO64: + case S3_TRIO32: + svga->hdisp >>= 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 +3734,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 +3742,90 @@ 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; + 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; + 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; + break; + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_SPEA_MERCURY_LITE_PCI: + svga->hdisp = (svga->hdisp << 1) / 3; + break; + default: + break; + } + break; + case S3_VISION864: + switch (s3->card_type) { + case S3_MIROCRYSTAL20SD_864: + svga->hdisp = (svga->hdisp << 1) / 3; + break; + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + switch (s3->width) { + case 1280: + svga->hdisp = (svga->hdisp << 1) / 3; + svga->hdisp <<= 1; + break; + default: + break; + } + break; + + default: + break; + } + break; + + case S3_TRIO64: + case S3_TRIO32: + svga->hdisp /= 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 +3833,93 @@ 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) 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; + 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; + break; + default: + break; + } + break; + case S3_ELSAWIN2KPROX_964: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + case S3_VISION968: + switch (s3->card_type) { + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + svga->hdisp <<= 1; + if (svga->hdisp == 832) + svga->hdisp -= 32; + break; + + case S3_ELSAWIN2KPROX: + switch (s3->width) { + case 1280: + case 1600: + svga->hdisp <<= 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,25 +3953,30 @@ 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; + svga->rowoffset <<= 1; } } - } else { - if (s3->chip <= S3_86C924) - s3->width = 1024; } } } @@ -3347,15 +3985,9 @@ s3_recalctimings(svga_t *svga) static void s3_trio64v_recalctimings(svga_t *svga) { - s3_t *s3 = (s3_t *) svga->priv; - 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; - } - } svga->hdisp = svga->hdisp_old; if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; @@ -3377,6 +4009,30 @@ 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[0x67] & 0xc) != 0xc) /*VGA mode*/ { svga->ma_latch |= (s3->ma_ext << 16); @@ -3387,9 +4043,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; @@ -3409,8 +4066,13 @@ s3_trio64v_recalctimings(svga_t *svga) 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,6 +4097,7 @@ 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; @@ -3453,6 +4116,9 @@ s3_trio64v_recalctimings(svga_t *svga) case 7: /*XRGB-32 (X.8.8.8)*/ svga->render = svga_render_32bpp_highres; break; + + default: + break; } } } @@ -3477,8 +4143,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 +4160,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 +4203,9 @@ s3_updatemapping(s3_t *s3) break; } break; + + default: + break; } s3->linear_base &= ~(s3->linear_size - 1); if (s3->linear_base == 0xa0000) { @@ -3544,11 +4215,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); } @@ -3583,12 +4253,13 @@ s3_updatemapping(s3_t *s3) static float s3_trio64_getclock(int clock, void *priv) { - s3_t *s3 = (s3_t *) priv; - 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) @@ -3641,8 +4312,10 @@ s3_accel_out(uint16_t port, uint8_t val, void *priv) svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); } - if (s3->chip > S3_86C924) - s3_updatemapping(s3); + s3_updatemapping(s3); + break; + + default: break; } } @@ -3682,6 +4355,7 @@ s3_accel_in(uint16_t port, void *priv) s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; int temp; + uint8_t temp2; if (!s3->enable_8514) return 0xff; @@ -3799,6 +4473,7 @@ s3_accel_in(uint16_t port, void *priv) temp |= 0x02; /*Hardware busy*/ else temp |= 0x04; /*FIFO empty*/ + s3->force_busy = 0; if (s3->chip >= S3_VISION964) { @@ -3811,9 +4486,30 @@ s3_accel_in(uint16_t port, void *priv) 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 +4540,12 @@ s3_accel_in(uint16_t port, void *priv) 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 +4553,49 @@ s3_accel_in(uint16_t port, void *priv) 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 +4603,50 @@ s3_accel_in(uint16_t port, void *priv) 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 +4654,101 @@ s3_accel_in(uint16_t port, void *priv) 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 +4756,38 @@ s3_accel_in(uint16_t port, void *priv) 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 +4836,9 @@ s3_accel_in(uint16_t port, void *priv) return s3->accel.setup_md & 0xff; case 0xa: return s3->accel.multifunc[0xd] & 0xff; + + default: + break; } return 0xff; } @@ -4052,6 +4873,9 @@ s3_accel_in(uint16_t port, void *priv) return (s3->accel.setup_md >> 8) & ~0xf000; case 0xa: return s3->accel.multifunc[0xd] >> 8; + + default: + break; } return 0xff; } @@ -4073,25 +4897,49 @@ s3_accel_in(uint16_t port, void *priv) 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 +4969,49 @@ s3_accel_in(uint16_t port, void *priv) 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 +5023,23 @@ s3_accel_in(uint16_t port, void *priv) 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 +5055,35 @@ s3_accel_in(uint16_t port, void *priv) 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 +5105,23 @@ s3_accel_in(uint16_t port, void *priv) 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,6 +5135,9 @@ s3_accel_in(uint16_t port, void *priv) if ((s3->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(s3->i2c)) temp |= SERIAL_PORT_SDR; return temp; + + default: + break; } return 0xff; @@ -4263,10 +5146,10 @@ s3_accel_in(uint16_t port, void *priv) static uint16_t s3_accel_in_w(uint16_t port, void *priv) { - s3_t *s3 = (s3_t *) priv; - 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 +5164,27 @@ s3_accel_in_w(uint16_t port, void *priv) 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 { @@ -4319,10 +5199,10 @@ s3_accel_in_w(uint16_t port, void *priv) static uint32_t s3_accel_in_l(UNUSED(uint16_t port), void *priv) { - s3_t *s3 = (s3_t *) priv; - 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 +5216,15 @@ s3_accel_in_l(UNUSED(uint16_t port), void *priv) 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 +5232,20 @@ s3_accel_in_l(UNUSED(uint16_t port), void *priv) 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; } } @@ -4372,8 +5255,8 @@ s3_accel_in_l(UNUSED(uint16_t port), void *priv) static void s3_accel_write(uint32_t addr, uint8_t val, void *priv) { - s3_t *s3 = (s3_t *) priv; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *) priv; + const svga_t *svga = &s3->svga; if (!s3->enable_8514) return; @@ -4390,8 +5273,8 @@ 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) { - s3_t *s3 = (s3_t *) priv; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *) priv; + const svga_t *svga = &s3->svga; if (!s3->enable_8514) return; @@ -4408,8 +5291,8 @@ 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) { - s3_t *s3 = (s3_t *) priv; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *) priv; + const svga_t *svga = &s3->svga; if (!s3->enable_8514) return; @@ -4504,20 +5387,23 @@ s3_accel_read(uint32_t addr, void *priv) 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; } } @@ -4529,10 +5415,10 @@ s3_accel_read(uint32_t addr, void *priv) static uint16_t s3_accel_read_w(uint32_t addr, void *priv) { - s3_t *s3 = (s3_t *) priv; - 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; @@ -4565,20 +5451,23 @@ s3_accel_read_w(uint32_t addr, void *priv) 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; } } @@ -4590,10 +5479,10 @@ s3_accel_read_w(uint32_t addr, void *priv) static uint32_t s3_accel_read_l(uint32_t addr, void *priv) { - s3_t *s3 = (s3_t *) priv; - 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; @@ -4736,31 +5625,34 @@ s3_accel_read_l(uint32_t addr, void *priv) 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; } } } @@ -4810,11 +5702,13 @@ polygon_setup(s3_t *s3) #define READ(addr, dat) \ 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 +5769,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) \ @@ -5663,12 +6557,15 @@ polygon_setup(s3_t *s3) 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 +6652,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 +6747,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 +6953,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) +s3_911_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv) { - 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) -{ - 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 +6967,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 +7003,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 +7019,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); } } @@ -6245,9 +7072,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; @@ -6257,33 +7089,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->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; - if (s3->accel.cur_y & 0x800) - s3->accel.cy |= ~0x7ff; - - 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)) 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; @@ -6291,15 +7149,16 @@ 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; @@ -6309,9 +7168,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ else cpu_dat >>= 16; - if (!s3->accel.sy) { + if (!s3->accel.sy) break; - } switch (s3->accel.cmd & 0xe0) { case 0x00: @@ -6342,13 +7200,811 @@ 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*/ + } 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) { + 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; + 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 = 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; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + + READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); + + MIX + + if (s3->accel.cmd & 0x10) { + WRITE((s3->accel.cy * s3->width) + 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.sy) + break; + + 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++; + 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 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 2: + src_dat = cpu_dat; + break; + 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; + s3->accel.cur_y = s3->accel.cy; + } + 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; + 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*/ count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; @@ -6363,10 +8019,10 @@ 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) { 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; @@ -6374,6 +8030,9 @@ 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) { @@ -6381,7 +8040,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); } } @@ -6395,77 +8054,48 @@ 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 { + else cpu_dat >>= 16; - } - 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: - s3->accel.cy++; - break; - case 0xa0: - s3->accel.cy++; - break; - case 0xc0: + else s3->accel.cx--; - break; - case 0xe0: - s3->accel.cx++; - break; - } + } else + s3->accel.err_term += s3->accel.desty_axstp; } else { - s3->accel.err_term += s3->accel.desty_axstp; + 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; } - /*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: - s3->accel.cy--; - break; - case 0x80: - s3->accel.cx--; - break; - case 0xa0: - s3->accel.cx++; - break; - case 0xc0: - s3->accel.cy++; - break; - case 0xe0: - s3->accel.cy++; - 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; @@ -6477,15 +8107,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; @@ -6526,13 +8149,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; @@ -6540,15 +8163,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); } } @@ -6565,30 +8191,31 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ 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.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--; @@ -6647,6 +8274,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) { @@ -6654,8 +8284,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); } } @@ -6690,27 +8319,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.dx = s3->accel.destx_distp & 0xfff; + s3->accel.dy = s3->accel.desty_axstp & 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.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -6729,16 +8346,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; @@ -6747,20 +8363,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); @@ -6768,10 +8386,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; @@ -6781,16 +8399,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; + + 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) && 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); } } @@ -6801,9 +8420,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++; @@ -6812,16 +8430,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) { @@ -6831,17 +8449,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; } } @@ -6856,18 +8475,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; @@ -6908,15 +8519,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); } } @@ -6924,7 +8537,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; @@ -6936,14 +8549,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; @@ -6955,6 +8569,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; @@ -6964,6 +8579,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; } } @@ -6985,12 +8602,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) @@ -7007,8 +8620,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); } } @@ -7021,12 +8633,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; @@ -7034,13 +8649,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); } } @@ -7053,11 +8667,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; @@ -7115,15 +8733,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); } } @@ -7177,18 +8797,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); @@ -7216,6 +8828,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) { @@ -7232,6 +8847,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) { @@ -7247,10 +8865,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 @@ -7280,13 +8901,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; @@ -7299,7 +8920,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); @@ -7314,14 +8934,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(UNUSED(int func), int addr, void *priv) { - s3_t *s3 = (s3_t *) priv; - svga_t *svga = &s3->svga; + const s3_t *s3 = (s3_t *) priv; + const svga_t *svga = &s3->svga; switch (addr) { case 0x00: @@ -7339,12 +8962,20 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) 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; 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*/ @@ -7371,6 +9002,7 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) return 0x00; else return (svga->crtc[0x5a] & 0x80); + break; case 0x13: if (svga->crtc[0x53] & 0x08) { @@ -7378,6 +9010,7 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) } else { return svga->crtc[0x59]; } + break; case 0x30: return s3->has_bios ? (s3->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ @@ -7395,9 +9028,11 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) case 0x3e: return (s3->chip == S3_TRIO64V2) ? 0x04 : 0x00; - break; case 0x3f: return (s3->chip == S3_TRIO64V2) ? 0xff : 0x00; + + default: + break; } return 0; } @@ -7480,6 +9115,9 @@ s3_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x3c: s3->int_line = val; return; + + default: + break; } } @@ -7518,6 +9156,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++; @@ -7587,6 +9228,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: @@ -7656,12 +9302,13 @@ s3_reset(void *priv) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + 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; @@ -7677,6 +9324,9 @@ s3_reset(void *priv) s3->pci_regs[0x3e] = 4; s3->pci_regs[0x3f] = 0xff; break; + + default: + break; } if (s3->has_bios) { @@ -7911,6 +9561,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; @@ -7955,7 +9610,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); } @@ -8009,12 +9664,34 @@ 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) { @@ -8084,6 +9761,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: @@ -8109,7 +9791,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; @@ -8175,7 +9857,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; @@ -8203,7 +9885,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*/ @@ -8226,13 +9908,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: @@ -8256,14 +9943,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; @@ -8314,21 +10007,21 @@ s3_init(const device_t *info) case S3_PHOENIX_TRIO64_ONBOARD: 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 +10052,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)); @@ -8553,6 +10250,12 @@ 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) { @@ -8859,7 +10562,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 = { @@ -9212,6 +10915,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 e52322426..ce9dda100 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -39,7 +39,6 @@ #include <86box/vid_ddc.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#include <86box/plat_unused.h> static int dither[4][4] = { {0, 4, 1, 5}, @@ -173,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; @@ -279,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; @@ -419,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 @@ -574,6 +575,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) 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; @@ -588,6 +592,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) 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; @@ -634,6 +641,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) 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) { @@ -649,6 +659,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } svga_out(addr, val, svga); } @@ -761,7 +774,7 @@ s3_virge_in(uint16_t addr, void *priv) static void s3_virge_recalctimings(svga_t *svga) { - virge_t *virge = (virge_t *) svga->priv; + const virge_t *virge = (virge_t *) svga->priv; svga->hdisp = svga->hdisp_old; @@ -838,6 +851,9 @@ 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; @@ -884,6 +900,9 @@ 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; } @@ -921,6 +940,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); @@ -946,6 +968,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); @@ -998,13 +1023,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; } } } @@ -1032,7 +1060,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; @@ -1467,6 +1494,9 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) queue_triangle(virge); } break; + + default: + break; } } } @@ -1480,15 +1510,24 @@ s3_virge_mmio_read(uint32_t addr, void *priv) 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: @@ -1552,6 +1591,9 @@ s3_virge_mmio_read(uint32_t addr, void *priv) if ((virge->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(virge->i2c)) ret |= SERIAL_PORT_SDR; return ret; + + default: + break; } return 0xff; } @@ -1565,15 +1607,19 @@ s3_virge_mmio_read_w(uint32_t addr, void *priv) 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; @@ -1661,21 +1707,19 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) 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; @@ -1808,6 +1852,9 @@ s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv) case 0x83df: s3_virge_out(addr & 0x3ff, val, virge); break; + + default: + break; } } } @@ -1970,6 +2017,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) virge->advfunc_cntl = val & 0xff; s3_virge_updatemapping(virge); break; + + default: + break; } } } @@ -2036,25 +2086,25 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) 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: @@ -2186,6 +2236,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); @@ -2222,6 +2275,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; @@ -2394,6 +2450,9 @@ skip_line: case CMD_SET_COMMAND_NOP: break; + + default: + break; } } @@ -3025,7 +3084,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); @@ -3043,7 +3105,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; @@ -3237,6 +3299,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; } } @@ -3255,7 +3320,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]; @@ -3265,6 +3330,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; @@ -3274,7 +3342,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); @@ -3288,6 +3356,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; } } @@ -3454,6 +3525,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) { @@ -3487,38 +3561,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->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; + 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) { @@ -3528,6 +3611,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; } @@ -3772,17 +3858,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->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]; + 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]); @@ -3816,9 +3902,9 @@ s3_virge_overlay_draw(svga_t *svga, int displine) static uint8_t s3_virge_pci_read(UNUSED(int func), int addr, void *priv) { - virge_t *virge = (virge_t *) priv; - 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: @@ -3971,6 +4057,9 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv) case 0xe3: ret = virge->pci_regs[0xe3]; break; + + default: + break; } return ret; } @@ -4054,6 +4143,9 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0xe2: virge->pci_regs[0xe2] = val & 0xc0; return; + + default: + break; } } @@ -4087,24 +4179,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; @@ -4134,6 +4231,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); @@ -4210,9 +4310,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); @@ -4263,6 +4363,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; @@ -4272,6 +4373,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; @@ -4281,6 +4383,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; @@ -4292,6 +4395,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; @@ -4305,11 +4409,10 @@ s3_virge_init(const device_t *info) case S3_VIRGE_GX: virge->virge_rev = 0x01; -#ifndef __APPLE__ - [[fallthrough]]; -#endif + fallthrough; default: + virge->fifo_slots_num = 8; virge->svga.decode_mask = (4 << 20) - 1; virge->virge_id_high = 0x8a; virge->virge_id_low = 0x01; @@ -4357,6 +4460,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); @@ -4365,7 +4471,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)); diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/vid_sc1148x_ramdac.c index ee75d192d..24ca4aeec 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 3a3b3a863..7315c65ad 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; -void -sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +static void +sc1502x_ramdac_bpp(uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) { - sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; - int oldbpp = 0; + 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 *priv, svga_t *svga) +{ + 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: - case 0x3C8: - case 0x3C9: + 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,21 +173,62 @@ sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga) ramdac->state++; break; case 0x3C7: - case 0x3C8: - case 0x3C9: 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: + if (ramdac->enable_ext) + temp = ramdac->idx; + else + ramdac->state = 0; + break; + + default: + break; } return temp; } 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 d68af2bfa..83796506e 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,6 +246,9 @@ sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) case 0x07: temp = ramdac->rindex; break; + + default: + break; } return temp; @@ -245,11 +257,11 @@ sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) float sdac_getclock(int clock, void *priv) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; - 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 97383bc65..56f8b99aa 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 @@ -256,6 +257,9 @@ sigma_out(uint16_t addr, uint8_t val, void *priv) else sigma->plane = val & 3; return; + + default: + break; } } @@ -326,6 +330,9 @@ sigma_in(uint16_t addr, void *priv) result = sigma->fake_stat; } break; + + default: + break; } return result; @@ -343,9 +350,10 @@ sigma_write(uint32_t addr, uint8_t val, void *priv) static uint8_t sigma_read(uint32_t addr, void *priv) { - sigma_t *sigma = (sigma_t *) priv; + const sigma_t *sigma = (sigma_t *) priv; cycles -= 4; + return sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)]; } @@ -364,8 +372,8 @@ sigma_bwrite(uint32_t addr, uint8_t val, void *priv) static uint8_t sigma_bread(uint32_t addr, void *priv) { - sigma_t *sigma = (sigma_t *) priv; - 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; @@ -772,12 +780,12 @@ sigma_poll(void *priv) } } -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"); diff --git a/src/video/vid_stg_ramdac.c b/src/video/vid_stg_ramdac.c index 64dd27def..187139b3b 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,6 +203,9 @@ 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); @@ -201,12 +214,12 @@ stg_ramdac_in(uint16_t addr, void *p, svga_t *svga) float stg_getclock(int clock, void *priv) { - stg_ramdac_t *ramdac = (stg_ramdac_t *) priv; - 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 *priv) } 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 a491bb5e1..f90c3f74e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -39,6 +39,8 @@ #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> @@ -56,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; @@ -91,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; @@ -110,15 +109,60 @@ svga_set_override(svga_t *svga, int val) void svga_out(uint16_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) priv; - 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; @@ -127,17 +171,19 @@ svga_out(uint16_t addr, uint8_t val, void *priv) } 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 (int 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; } @@ -167,10 +213,15 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga_recalctimings(svga); break; case 0x3c3: - if (xga_enabled) { - svga->xga.on = (val & 0x01) ? 0 : 1; - vga_on = !svga->xga.on; + 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; break; case 0x3c4: svga->seqaddr = val; @@ -205,21 +256,20 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga->chain4 = 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; @@ -235,9 +285,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv) 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 @@ -245,6 +296,9 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga->dac_pos = 0; svga->dac_addr = (svga->dac_addr + 1) & 255; break; + + default: + break; } break; case 0x3ce: @@ -283,29 +337,82 @@ svga_out(uint16_t addr, uint8_t val, void *priv) 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; + + default: + break; } } uint8_t svga_in(uint16_t addr, void *priv) { - svga_t *svga = (svga_t *) priv; - 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; @@ -318,25 +425,24 @@ svga_in(uint16_t addr, void *priv) 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) { @@ -362,6 +468,9 @@ svga_in(uint16_t addr, void *priv) else ret = svga->vgapal[index].b & 0x3f; break; + + default: + break; } if (svga->adv_flags & FLAG_RAMDAC_SHIFT) ret >>= 2; @@ -403,6 +512,9 @@ svga_in(uint16_t addr, void *priv) ret = svga->cgastat; break; + + default: + break; } return ret; @@ -411,10 +523,29 @@ svga_in(uint16_t addr, void *priv) 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 (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 @@ -428,10 +559,11 @@ svga_set_ramdac_type(svga_t *svga, int type) void svga_recalctimings(svga_t *svga) { - double crtcconst; - double _dispontime; - double _dispofftime; - double disptime; + const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + double crtcconst; + double _dispontime; + double _dispofftime; + double disptime; svga->vtotal = svga->crtc[6]; svga->dispend = svga->crtc[0x12]; @@ -474,20 +606,20 @@ svga_recalctimings(svga_t *svga) 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; @@ -508,61 +640,68 @@ svga_recalctimings(svga_t *svga) 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; + } } } } @@ -570,12 +709,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; @@ -585,24 +722,22 @@ svga_recalctimings(svga_t *svga) } else svga->monitor->mon_overscan_x = 16; - if (vga_on) { - if (svga->recalctimings_ex) { - svga->recalctimings_ex(svga); - } - } else { - if (ibm8514_enabled) { - if (svga->dev8514.local) { - if (svga->recalctimings_ex) { - svga->recalctimings_ex(svga); - } - } else - ibm8514_recalctimings(svga); - } - if (xga_enabled) - xga_recalctimings(svga); + if (svga->recalctimings_ex) { + svga->recalctimings_ex(svga); } - svga->y_add = (svga->monitor->mon_overscan_y >> 1) - (svga->crtc[8] & 0x1f); + if (ibm8514_active && (svga->dev8514 != NULL)) { + if ((dev->local & 0xff) == 0x00) + ibm8514_recalctimings(svga); + } + + if (xga_active && (svga->xga != NULL)) + xga_recalctimings(svga); + + 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) @@ -610,13 +745,8 @@ svga_recalctimings(svga_t *svga) crtcconst = svga->clock * svga->char_width; - if (ibm8514_on && !svga->dev8514.local) { - disptime = svga->dev8514.h_total; - _dispontime = svga->dev8514.h_disp; - } else { - disptime = svga->htotal; - _dispontime = svga->hdisp_time; - } + disptime = svga->htotal; + _dispontime = svga->hdisp_time; if (svga->seqregs[1] & 8) { disptime *= 2; @@ -695,24 +825,27 @@ svga_do_render(svga_t *svga) void svga_poll(void *priv) { - svga_t *svga = (svga_t *) priv; - ibm8514_t *dev = &svga->dev8514; - uint32_t x; - uint32_t blink_delay; - int wx; - int wy; - int ret; - int old_ma; - int linecountff = 0; + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + xga_t *xga = (xga_t *) svga->xga; + uint32_t x; + uint32_t blink_delay; + int wx; + int wy; + int ret; + int old_ma; - if (!vga_on && ibm8514_enabled && ibm8514_on) { - if (!dev->local) { + if (!svga->override) { + if (ibm8514_active && dev && (dev->on[0] || dev->on[1])) { ibm8514_poll(dev, svga); return; } - } else if (!vga_on && xga_enabled && svga->xga.on) { - xga_poll(&svga->xga, svga); - return; + if (xga_active && xga && xga->on) { + if ((xga->disp_cntl_2 & 7) >= 2) { + xga_poll(xga, svga); + return; + } + } } if (!svga->linepos) { @@ -792,7 +925,7 @@ svga_poll(void *priv) 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); @@ -805,14 +938,10 @@ svga_poll(void *priv) if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount)) svga->con = 0; if (svga->dispon) { - /*Real IBM 8514/A or compatibility mode doesn't have linedbl, so skip those.*/ - if (dev->local && ibm8514_on) { - svga->linedbl = 0; - svga->linecountff = 0; - linecountff = 1; - } - if (svga->linedbl && !svga->linecountff && !linecountff) { - svga->linecountff = 1; + /* 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; } else if (svga->sc == svga->rowcount) { svga->linecountff = 0; @@ -874,7 +1003,7 @@ svga_poll(void *priv) 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; @@ -917,20 +1046,14 @@ svga_poll(void *priv) svga->oddeven ^= 1; svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2; - svga->vslines = 0; + svga->vslines = 0; - if ((dev->local && vga_on) || !dev->local) { - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); - else - svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); - } else if (dev->local && ibm8514_on) { - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); - else - svga->ma = svga->maback = svga->ma_latch; - } - svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + 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->ma << 2); svga->maback = (svga->maback << 2); svga->ca = (svga->ca << 2); @@ -940,28 +1063,26 @@ svga_poll(void *priv) } 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; @@ -981,6 +1102,12 @@ svga_poll(void *priv) } } +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 *priv, int memsize, void (*recalctimings_ex)(struct svga_t *svga), @@ -991,9 +1118,9 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, { int e; - svga->priv = priv; + svga->priv = priv; svga->monitor_index = monitor_index_global; - svga->monitor = &monitors[svga->monitor_index]; + svga->monitor = &monitors[svga->monitor_index]; for (int c = 0; c < 256; c++) { e = c; @@ -1007,10 +1134,10 @@ svga_init(const device_t *info, svga_t *svga, void *priv, 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; @@ -1027,6 +1154,7 @@ svga_init(const device_t *info, svga_t *svga, void *priv, 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; @@ -1121,12 +1249,12 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write) static __inline void svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) { - svga_t *svga = (svga_t *) priv; - + 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; @@ -1136,24 +1264,38 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) 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); @@ -1182,18 +1324,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) if (addr & 1) writemask2 <<= 1; addr &= ~1; - if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) { - addr &= svga->vram_mask; - } else - addr <<= 2; - } else { - if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) { - writemask2 = 1 << (addr & 3); - addr &= ~3; - addr &= svga->vram_mask; - } else - addr <<= 2; - } + addr <<= 2; + } else + addr <<= 2; + addr &= svga->decode_mask; if (svga->translate_address) @@ -1325,6 +1459,9 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) } } break; + + default: + break; } if (reset_wm) @@ -1335,6 +1472,7 @@ static __inline uint8_t svga_read_common(uint32_t addr, uint8_t linear, void *priv) { 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; @@ -1347,23 +1485,37 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv) 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; + 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 += svga->xga.read_bank; - return svga->xga.vram[addr & svga->xga.vram_mask]; + 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); @@ -1399,22 +1551,10 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv) } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); addr &= ~1; - if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) - addr &= svga->vram_mask; - else - addr <<= 2; - } else { - if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) { - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - latch_addr = (addr & svga->vram_mask) & ~3; - for (uint8_t i = 0; i < count; i++) - svga->latch.b[i] = svga->vram[latch_addr | i]; - return svga->vram[addr & svga->vram_mask]; - } else - addr <<= 2; - } + addr <<= 2; + } else + addr <<= 2; + addr &= svga->decode_mask; if (svga->translate_address) { @@ -1500,7 +1640,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; @@ -1583,8 +1723,8 @@ svga_writeb_linear(uint32_t addr, uint8_t val, void *priv) 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 @@ -1710,7 +1850,7 @@ svga_writel_linear(uint32_t addr, uint32_t val, void *priv) uint8_t svga_readb_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) priv; + const svga_t *svga = (svga_t *) priv; if (!svga->fast) return svga_read_linear(addr, priv); @@ -1719,7 +1859,7 @@ svga_readb_linear(uint32_t addr, void *priv) 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 @@ -1741,8 +1881,8 @@ svga_readw_common(uint32_t addr, uint8_t linear, void *priv) addr &= svga->decode_mask; if (svga->translate_address) { - uint8_t val1 = 0xff; - uint8_t val2 = 0xff; + 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]; @@ -1774,9 +1914,8 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *priv) { svga_t *svga = (svga_t *) priv; - if (!svga->fast) { + 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; @@ -1789,10 +1928,10 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *priv) addr &= svga->decode_mask; if (svga->translate_address) { - uint8_t val1 = 0xff; - uint8_t val2 = 0xff; - uint8_t val3 = 0xff; - uint8_t val4 = 0xff; + 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]; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index af4cb83da..20c1e6e5e 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,6 +80,9 @@ svga_render_blank(svga_t *svga) case 9: char_width = 16; break; + + default: + break; } uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; @@ -389,202 +407,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,16 +462,257 @@ 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_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) + changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + else + changed_offset = svga->remap_func(svga, svga->ma) >> 12; + + 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]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + 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; + + /* 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 { + /* 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); + } + } + } 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); + } + load_counter += 1; + if (load_counter >= loadevery) + load_counter = 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; + } + + 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 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; + } + } 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_8bpp_incompatible_highres(svga_t *svga) +{ + int x; + uint32_t *p; + uint32_t dat; uint32_t changed_addr; + uint32_t addr; if ((svga->displine + svga->y_add) < 0) return; @@ -662,55 +725,23 @@ svga_render_4bpp_lowres(svga_t *svga) 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; + 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->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_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]; - 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); - - 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] = 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; + svga->ma += 8; + p += 8; } + svga->ma &= svga->vram_display_mask; } } else { changed_addr = svga->remap_func(svga, svga->ma); @@ -722,161 +753,43 @@ svga_render_4bpp_lowres(svga_t *svga) 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; + 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]; - 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; + 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; + } 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]; - 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; - } - } - } -} - -void -svga_render_4bpp_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 changed_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) { - 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); - - 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]]; - - 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); - 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; - } - 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]]; - - 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 +944,7 @@ svga_render_8bpp_highres(svga_t *svga) } } } +#endif void svga_render_8bpp_tseng_lowres(svga_t *svga) @@ -1154,13 +1068,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 +1093,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 +1107,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 +1139,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 +1170,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 +1191,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 +1219,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 +1255,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 +1300,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 +1325,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 +1339,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 +1371,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 +1402,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 +1423,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 +1462,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 +1481,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 +1497,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 +1535,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 +1566,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 +1582,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 +1617,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 +1633,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 +1673,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 +1691,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 +1732,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 +1772,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 aaf407ca4..844baa97a 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -38,7 +38,7 @@ #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; @@ -77,196 +77,198 @@ static const device_t vid_internal_device = { static const VIDEO_CARD video_cards[] = { // clang-format off - { &vid_none_device }, - { &vid_internal_device }, - { &atiega_device }, - { &mach8_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 }, + { &vid_none_device }, + { &vid_internal_device }, + { &atiega800p_device }, + { &mach8_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 }, - { &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_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 }, - { &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_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 }, - { &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 }, - { &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_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 }, + { &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 }, + { &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 }, + { &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 }, + { &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 }; @@ -343,8 +345,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(); @@ -353,21 +363,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 @@ -400,7 +429,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); @@ -412,7 +441,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++; } diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index f659f90fe..7bed43ac2 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 : @@ -103,7 +103,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 +129,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; @@ -219,11 +223,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 @@ -326,6 +329,9 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) if (!(svga->gdcreg[0xf] & 1)) svga->read_bank = svga->write_bank; return; + + default: + break; } break; @@ -415,6 +421,9 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) case 0x5f: svga->gdcreg[svga->gdcaddr] = val; break; + + default: + break; } break; case 0x3D4: @@ -488,6 +497,9 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((val & 1) ? 64 : 32); } break; + + default: + break; } if (old != val) { @@ -496,7 +508,7 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) 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,6 +538,9 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) tgui->clock_m = (tgui->clock_m & ~0x1e) | ((val << 1) & 0x1e); tgui->clock_k = (val & 0x10) >> 4; break; + + default: + break; } svga_out(addr, val, svga); } @@ -556,6 +571,9 @@ tgui_in(uint16_t addr, void *priv) case TGUI_9660: case TGUI_9680: return 0xd3; /*TGUI9660XGi*/ + + default: + break; } } if (svga->seqaddr == 0x0d) { @@ -617,6 +635,9 @@ tgui_in(uint16_t addr, void *priv) return tgui->tgui_3d8; case 0x3d9: return tgui->tgui_3d9; + + default: + break; } return svga_in(addr, svga); } @@ -624,9 +645,9 @@ tgui_in(uint16_t addr, void *priv) void tgui_recalctimings(svga_t *svga) { - tgui_t *tgui = (tgui_t *) svga->priv; - 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 +655,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 +744,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 +760,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 +807,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,6 +884,9 @@ tgui_recalcmapping(tgui_t *tgui) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } } } else { @@ -879,6 +915,9 @@ tgui_recalcmapping(tgui_t *tgui) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; + + default: + break; } } @@ -906,14 +945,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 +966,9 @@ tgui_hwcursor_draw(svga_t *svga, int displine) } uint8_t -tgui_pci_read(int func, int addr, void *priv) +tgui_pci_read(UNUSED(int func), int addr, void *priv) { - tgui_t *tgui = (tgui_t *) priv; + const tgui_t *tgui = (tgui_t *) priv; switch (addr) { case 0x00: @@ -989,12 +1028,15 @@ tgui_pci_read(int func, int addr, void *priv) 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 *priv) +tgui_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { tgui_t *tgui = (tgui_t *) priv; svga_t *svga = &tgui->svga; @@ -1060,6 +1102,9 @@ tgui_pci_write(int func, int addr, uint8_t val, void *priv) case 0x3c: tgui->int_line = val; return; + + default: + break; } } @@ -1075,15 +1120,20 @@ tgui_ext_linear_read(uint32_t addr, void *priv) 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 @@ -1099,12 +1149,13 @@ tgui_ext_read(uint32_t addr, void *priv) static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) priv; - tgui_t *tgui = (tgui_t *) svga->priv; - 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 +1163,65 @@ tgui_ext_linear_write(uint32_t addr, uint8_t val, void *priv) 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; + svga->changedvram[addr >> 12] = svga->monitor->mon_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; + 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; - - /*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; + } 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; - - /*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; - } - 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; - } - break; - } + } + } else + svga_write_linear(addr, val, svga); } static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) priv; - tgui_t *tgui = (tgui_t *) svga->priv; - 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,70 +1229,82 @@ tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *priv) 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; + 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, 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; + 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]; - /*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; + addr += (c & 3) ? 1 : 13; + addr &= svga->vram_mask; + } } - break; - - /*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; - } - 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 + c] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; - } - break; - } + } + } else + svga_writew_linear(addr, val, svga); } static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *priv) { - tgui_ext_linear_writew(addr, val, priv); + 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 @@ -1257,7 +1312,7 @@ tgui_ext_write(uint32_t addr, uint8_t val, void *priv) { 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); } @@ -1266,7 +1321,7 @@ tgui_ext_writew(uint32_t addr, uint16_t val, void *priv) { 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); } @@ -1275,7 +1330,7 @@ tgui_ext_writel(uint32_t addr, uint32_t val, void *priv) { 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 +1380,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 +1414,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 +1462,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; + /* See Linux kernel drivers/video/tridentfb.c for the pitch */ + tgui->accel.pitch = svga->rowoffset; + + switch (svga->bpp) { + case 8: + case 24: + tgui->accel.pitch <<= 3; 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; + case 15: + case 16: + tgui->accel.pitch <<= 2; break; - case 1600: - tgui->accel.pitch = 2048; + case 32: + tgui->accel.pitch <<= 1; break; } - - 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; - } - 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; - } - } - 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 +1699,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); + + 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.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { + MIX(); + + WRITE(tgui->accel.dst, out); } - while (count--) { - READ(tgui->accel.src, src_dat); - READ(tgui->accel.dst, dst_dat); + tgui->accel.src += xdir; + tgui->accel.dst += xdir; + tgui->accel.pat_x += xdir; - pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)]; + tgui->accel.x++; + if (tgui->accel.x > tgui->accel.size_x) { + tgui->accel.x = 0; - 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(); - - WRITE(tgui->accel.dst, out); - } - - 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.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 +1748,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 +1764,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--; - break; - case 0x100: - tgui->accel.dy--; - break; - case 0x700: - tgui->accel.dx--; - break; - case 0x500: - tgui->accel.dx++; - break; - case 0x200: + switch ((tgui->accel.flags >> 8) & 7) { + case 0: + case 2: tgui->accel.dy++; break; - case 0x000: - tgui->accel.dy++; + case 1: + case 3: + tgui->accel.dy--; break; - case 0x600: - tgui->accel.dx--; - break; - case 0x400: + case 4: + case 5: tgui->accel.dx++; 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; - } + case 6: + case 7: + tgui->accel.dx--; + break; + + default: + break; + } + } 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 +1839,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 +1855,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 +1899,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 +1917,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 +1933,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,11 +1977,19 @@ 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; } } @@ -1998,49 +1997,45 @@ static void tgui_accel_out(uint16_t addr, uint8_t val, void *priv) { 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 +2115,37 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *priv) 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,6 +2331,9 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *priv) case 0x21ff: tgui->accel.pattern[addr & 0x7f] = val; break; + + default: + break; } } @@ -2371,7 +2370,7 @@ tgui_accel_out_l(uint16_t addr, uint32_t val, void *priv) static uint8_t tgui_accel_in(uint16_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) priv; + const tgui_t *tgui = (tgui_t *) priv; switch (addr) { case 0x2120: /*Status*/ @@ -2617,6 +2616,9 @@ tgui_accel_in(uint16_t addr, void *priv) case 0x21fe: case 0x21ff: return tgui->accel.pattern[addr & 0x7f]; + + default: + break; } return 0; } @@ -2649,343 +2651,7 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *priv) 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; - - case 9: - switch (tgui->svga.bpp) { - case 32: - tgui->accel.bpp = 3; - break; - default: - tgui->accel.bpp = 1; - break; - } - 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; - } - break; - } - 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; - } + tgui_accel_out((addr & 0xff) + 0x2100, val, tgui); } static void @@ -3000,8 +2666,8 @@ tgui_accel_write_w(uint32_t addr, uint16_t val, void *priv) static void tgui_accel_write_l(uint32_t addr, uint32_t val, void *priv) { - tgui_t *tgui = (tgui_t *) priv; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; switch (addr & 0xff) { case 0x24: /*Long version of Command and ROP together*/ @@ -3028,8 +2694,8 @@ tgui_accel_write_l(uint32_t addr, uint32_t val, void *priv) static uint8_t tgui_accel_read(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) priv; - 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,6 +2949,9 @@ tgui_accel_read(uint32_t addr, void *priv) case 0xfe: case 0xff: return tgui->accel.pattern[addr & 0x7f]; + + default: + break; } return 0xff; } @@ -3342,8 +3011,8 @@ tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv) static void tgui_mmio_write(uint32_t addr, uint8_t val, void *priv) { - tgui_t *tgui = (tgui_t *) priv; - svga_t *svga = &tgui->svga; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; addr &= 0x0000ffff; @@ -3358,8 +3027,8 @@ tgui_mmio_write(uint32_t addr, uint8_t val, void *priv) static void tgui_mmio_write_w(uint32_t addr, uint16_t val, void *priv) { - tgui_t *tgui = (tgui_t *) priv; - svga_t *svga = &tgui->svga; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; addr &= 0x0000ffff; @@ -3376,8 +3045,8 @@ tgui_mmio_write_w(uint32_t addr, uint16_t val, void *priv) static void tgui_mmio_write_l(uint32_t addr, uint32_t val, void *priv) { - tgui_t *tgui = (tgui_t *) priv; - svga_t *svga = &tgui->svga; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; addr &= 0x0000ffff; @@ -3396,8 +3065,8 @@ tgui_mmio_write_l(uint32_t addr, uint32_t val, void *priv) static uint8_t tgui_mmio_read(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) priv; - svga_t *svga = &tgui->svga; + const tgui_t *tgui = (tgui_t *) priv; + const svga_t *svga = &tgui->svga; uint8_t ret = 0xff; @@ -3416,9 +3085,9 @@ tgui_mmio_read(uint32_t addr, void *priv) static uint16_t tgui_mmio_read_w(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) priv; - 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; @@ -3435,9 +3104,9 @@ tgui_mmio_read_w(uint32_t addr, void *priv) static uint32_t tgui_mmio_read_l(uint32_t addr, void *priv) { - tgui_t *tgui = (tgui_t *) priv; - 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; @@ -3486,7 +3155,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); } @@ -3512,13 +3181,16 @@ 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; @@ -3585,7 +3257,7 @@ tgui_force_redraw(void *priv) { tgui_t *tgui = (tgui_t *) priv; - tgui->svga.fullchange = changeframecount; + tgui->svga.fullchange = tgui->svga.monitor->mon_changeframecount; } // clang-format off diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c index 32c37ca8b..f23cb7396 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 66c2ca922..4108b9a4e 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 8483bbd33..591851016 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -111,6 +111,9 @@ tvga_out(uint16_t addr, uint8_t val, void *priv) tvga_recalcbanking(tvga); } return; + + default: + break; } break; @@ -143,6 +146,9 @@ tvga_out(uint16_t addr, uint8_t val, void *priv) 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 *priv) case 0x1e: svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; break; + + default: + break; } return; case 0x3D8: @@ -194,6 +203,9 @@ tvga_out(uint16_t addr, uint8_t val, void *priv) svga_recalctimings(svga); } break; + + default: + break; } svga_out(addr, val, svga); } @@ -241,6 +253,9 @@ tvga_in(uint16_t addr, void *priv) 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->priv; - 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, diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index da75543ca..a28cc2aed 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,10 +50,16 @@ 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 @@ -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,45 @@ 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); + /* TODO: Figure out gamma correction for 15/16 bpp color. */ + svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); +} + +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 +559,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]; @@ -513,6 +606,9 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] = clr3; break; + + default: + break; } break; case 2: /* XGA */ @@ -526,6 +622,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 +635,14 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) case 3: p[x_pos] = clr2; break; + + default: + break; } break; + + default: + break; } } offset++; @@ -552,12 +657,12 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) float tvp3026_getclock(int clock, void *priv) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; - 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 +674,24 @@ tvp3026_getclock(int clock, void *priv) 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 cd70a1bc1..43b8a2750 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -69,6 +69,9 @@ vga_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } svga_out(addr, val, svga); } diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 610e15e6c..a34f26503 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -160,8 +160,8 @@ voodoo_readw(uint32_t addr, void *priv) 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]; @@ -194,13 +194,12 @@ voodoo_readl(uint32_t addr, void *priv) 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]; @@ -429,7 +428,9 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) { 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 *priv) 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 *priv) 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 *priv) 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 *priv) 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 *priv) 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: @@ -672,14 +684,14 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) static uint16_t voodoo_snoop_readw(uint32_t addr, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) priv; + 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 *priv) { - voodoo_set_t *set = (voodoo_set_t *) priv; + const voodoo_set_t *set = (voodoo_set_t *) priv; return voodoo_readl(addr, set->voodoos[0]); } @@ -687,7 +699,7 @@ voodoo_snoop_readl(uint32_t addr, void *priv) static void voodoo_snoop_writew(uint32_t addr, uint16_t val, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) priv; + const voodoo_set_t *set = (voodoo_set_t *) priv; voodoo_writew(addr, val, set->voodoos[0]); voodoo_writew(addr, val, set->voodoos[1]); @@ -695,7 +707,7 @@ voodoo_snoop_writew(uint32_t addr, uint16_t val, void *priv) static void voodoo_snoop_writel(uint32_t addr, uint32_t val, void *priv) { - voodoo_set_t *set = (voodoo_set_t *) priv; + const voodoo_set_t *set = (voodoo_set_t *) priv; voodoo_writel(addr, val, set->voodoos[0]); voodoo_writel(addr, val, set->voodoos[1]); @@ -749,7 +761,7 @@ voodoo_recalcmapping(voodoo_set_t *set) uint8_t voodoo_pci_read(int func, int addr, void *priv) { - voodoo_t *voodoo = (voodoo_t *) priv; + const voodoo_t *voodoo = (voodoo_t *) priv; if (func) return 0; @@ -803,6 +815,9 @@ voodoo_pci_read(int func, int addr, void *priv) return (voodoo->initEnable >> 16) & 0xff; case 0x43: return (voodoo->initEnable >> 24) & 0xff; + + default: + break; } return 0; } @@ -844,13 +859,16 @@ voodoo_pci_write(int func, int addr, uint8_t val, void *priv) voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24); voodoo_recalcmapping(voodoo->set); break; + + default: + break; } } static void voodoo_speed_changed(void *priv) { - voodoo_set_t *voodoo_set = (voodoo_set_t *) priv; + 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); @@ -870,7 +888,7 @@ voodoo_speed_changed(void *priv) static void voodoo_force_blit(void *priv) { - voodoo_set_t *voodoo_set = (voodoo_set_t *) priv; + 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) { @@ -916,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*/ @@ -923,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); @@ -1163,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; @@ -1205,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; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 0b3a3a043..23236be6f 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,9 +312,9 @@ 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); } } @@ -370,6 +376,9 @@ banshee_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } svga_out(addr, val, svga); } @@ -430,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; @@ -448,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); @@ -457,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->priv; - uint32_t *p = &((uint32_t *) svga->monitor->target_buffer->line[svga->displine + svga->y_add])[svga->x_add]; + uint32_t *p = &(svga->monitor->target_buffer->line[svga->displine + svga->y_add])[svga->x_add]; uint32_t addr; int drawn = 0; @@ -477,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 @@ -500,8 +537,8 @@ banshee_render_16bpp_tiled(svga_t *svga) static void banshee_recalctimings(svga_t *svga) { - banshee_t *banshee = (banshee_t *) svga->priv; - 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 @@ -757,6 +794,7 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv) break; case Init_vgaInit0: banshee->vgaInit0 = val; + svga_set_ramdac_type(svga, (val & VGAINIT0_RAMDAC_8BIT ? RAMDAC_8BIT : RAMDAC_6BIT)); break; case Init_vgaInit1: banshee->vgaInit1 = val; @@ -796,6 +834,7 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv) 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; @@ -905,10 +944,11 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv) svga->fullchange = changeframecount; svga_recalctimings(svga); break; -#if 0 default: +#if 0 fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val); #endif + break; } } @@ -996,15 +1036,14 @@ banshee_ext_in(uint16_t addr, void *priv) 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 @@ -1037,10 +1076,10 @@ banshee_status(banshee_t *banshee) static uint32_t banshee_ext_inl(uint16_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - 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; @@ -1212,8 +1251,8 @@ banshee_reg_readw(uint32_t addr, void *priv) 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: @@ -1419,6 +1458,9 @@ banshee_reg_readl(uint32_t addr, void *priv) break; } break; + + default: + break; } #if 0 @@ -1467,6 +1509,9 @@ banshee_reg_writew(uint32_t addr, uint16_t val, void *priv) case 0x1f00000: voodoo_queue_command(voodoo, (addr & 0xffffff) | FIFO_WRITEW_FB, val); break; + + default: + break; } } @@ -1679,15 +1724,18 @@ banshee_reg_writel(uint32_t addr, uint32_t val, void *priv) 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 *priv) { - banshee_t *banshee = (banshee_t *) priv; - 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; @@ -1723,9 +1771,9 @@ banshee_read_linear(uint32_t addr, void *priv) static uint16_t banshee_read_linear_w(uint32_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - 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, priv) | (banshee_read_linear(addr + 1, priv) << 8); @@ -1763,9 +1811,9 @@ banshee_read_linear_w(uint32_t addr, void *priv) static uint32_t banshee_read_linear_l(uint32_t addr, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - 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, priv) | (banshee_read_linear_w(addr + 2, priv) << 16); @@ -1804,9 +1852,9 @@ banshee_read_linear_l(uint32_t addr, void *priv) static void banshee_write_linear(uint32_t addr, uint8_t val, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - 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; @@ -1839,9 +1887,9 @@ banshee_write_linear(uint32_t addr, uint8_t val, void *priv) static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *priv) { - banshee_t *banshee = (banshee_t *) priv; - 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, priv); @@ -1981,14 +2029,14 @@ banshee_write_linear_l(uint32_t addr, uint32_t val, void *priv) void banshee_hwcursor_draw(svga_t *svga, int displine) { - 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]; + 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]; @@ -2004,7 +2052,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; @@ -2019,9 +2067,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; @@ -2186,8 +2234,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; @@ -2201,10 +2247,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; @@ -2286,10 +2330,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; @@ -2329,18 +2371,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->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; - 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); @@ -2354,7 +2396,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)); @@ -2608,7 +2650,7 @@ banshee_vsync_callback(svga_t *svga) static uint8_t banshee_pci_read(int func, int addr, void *priv) { - banshee_t *banshee = (banshee_t *) priv; + const banshee_t *banshee = (banshee_t *) priv; #if 0 svga_t *svga = &banshee->svga; #endif @@ -2803,6 +2845,9 @@ banshee_pci_read(int func, int addr, void *priv) case 0x67: ret = banshee->pci_regs[0x67]; break; + + default: + break; } #if 0 banshee_log("%02X\n", ret); @@ -2932,6 +2977,9 @@ banshee_pci_write(int func, int addr, uint8_t val, void *priv) case 0x66: banshee->pci_regs[0x66] = val & 0xc0; return; + + default: + break; } } @@ -3146,10 +3194,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; @@ -3168,6 +3219,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) { @@ -3238,6 +3291,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); diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index f5009e0b8..33ee602b5 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -250,6 +250,9 @@ 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; } } @@ -293,6 +296,9 @@ PLOT_LINE(voodoo_t *voodoo, int x, int y, UNUSED(uint8_t rop), uint32_t pattern, 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; } } @@ -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 ff45fc837..6ea2edcc3 100644 --- a/src/video/vid_voodoo_blitter.c +++ b/src/video/vid_voodoo_blitter.c @@ -163,8 +163,6 @@ 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; #if 0 voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", @@ -175,13 +173,13 @@ voodoo_v2_blit_start(voodoo_t *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; @@ -233,7 +231,7 @@ skip_pixel_blit: 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; @@ -244,7 +242,7 @@ skip_pixel_blit: } 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; @@ -267,7 +265,7 @@ skip_line_fill: 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*/ @@ -284,7 +282,7 @@ skip_line_fill: 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++; @@ -347,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; @@ -375,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: @@ -392,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 84f376a8f..e6cf13674 100644 --- a/src/video/vid_voodoo_display.c +++ b/src/video/vid_voodoo_display.c @@ -509,8 +509,8 @@ voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, void voodoo_callback(void *priv) { - voodoo_t *voodoo = (voodoo_t *) priv; - 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) { diff --git a/src/video/vid_voodoo_fb.c b/src/video/vid_voodoo_fb.c index 5e06836b1..94394e115 100644 --- a/src/video/vid_voodoo_fb.c +++ b/src/video/vid_voodoo_fb.c @@ -76,7 +76,7 @@ voodoo_fb_readw(uint32_t addr, void *priv) } if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; + const voodoo_set_t *set = voodoo->set; if (y & 1) voodoo = set->voodoos[1]; @@ -117,7 +117,7 @@ voodoo_fb_readl(uint32_t addr, void *priv) } if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; + const voodoo_set_t *set = voodoo->set; if (y & 1) voodoo = set->voodoos[1]; @@ -170,16 +170,16 @@ do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) void voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) priv; - 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; @@ -310,17 +310,17 @@ skip_pixel: void voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) { - voodoo_t *voodoo = (voodoo_t *) priv; - 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; diff --git a/src/video/vid_voodoo_fifo.c b/src/video/vid_voodoo_fifo.c index 8a84dabe4..f8495edec 100644 --- a/src/video/vid_voodoo_fifo.c +++ b/src/video/vid_voodoo_fifo.c @@ -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); } diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index 4a66161f5..ce3ee6064 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -105,7 +105,7 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv) 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--; @@ -1121,6 +1121,7 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv) } break; } + fallthrough; case SST_nccTable0_I2: if (!(val & (1 << 31))) { if (chip & CHIP_TREX0) { @@ -1359,5 +1360,8 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv) 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 052a0b51e..42426744a 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -475,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; @@ -520,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; @@ -575,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; @@ -622,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; @@ -1073,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) { @@ -1460,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 8b8f1366d..3939db3cd 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; + 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; - // 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]); +#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: @@ -566,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; diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index 6695709cc..600fa21a8 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 @@ -283,13 +284,17 @@ wy700_out(uint16_t addr, uint8_t val, void *priv) case 0x3D9: wy700->cga_colour = val; return; + + default: + break; } } uint8_t wy700_in(uint16_t addr, void *priv) { - wy700_t *wy700 = (wy700_t *) priv; + const wy700_t *wy700 = (wy700_t *) priv; + switch (addr) { case 0x3b0: case 0x3b2: @@ -318,6 +323,9 @@ wy700_in(uint16_t addr, void *priv) 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) { @@ -477,9 +488,9 @@ wy700_write(uint32_t addr, uint8_t val, void *priv) uint8_t wy700_read(uint32_t addr, void *priv) { - wy700_t *wy700 = (wy700_t *) priv; - 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)) @@ -857,10 +877,11 @@ wy700_poll(void *priv) } 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); diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 50cfcb90a..17b6dfdb5 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,13 +30,15 @@ #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 }; @@ -45,7 +47,32 @@ static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .writ static void xga_ext_outb(uint16_t addr, uint8_t val, void *priv); static uint8_t xga_ext_inb(uint16_t addr, void *priv); -int xga_has_vga = 0; +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) @@ -81,6 +108,9 @@ svga_xga_out(uint16_t addr, uint8_t val, void *priv) } } break; + + default: + break; } svga_out(addr, val, svga); } @@ -114,12 +144,15 @@ svga_xga_in(uint16_t addr, void *priv) 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, 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); if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) { if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) { - mem_mapping_disable(&svga->mapping); if (xga->aperture_cntl == 1) mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); else @@ -130,7 +163,6 @@ xga_updatemapping(svga_t *svga) 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; @@ -138,25 +170,24 @@ xga_updatemapping(svga_t *svga) 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; - } + if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) { xga->on = 0; - vga_on = !xga->on; + vga_on = 1; + xga_log("A5 test valid.\n"); } } - //pclog("XGA opmode (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.\n", xga->op_mode & 7, + xga->disp_cntl_2 & 7, xga->aperture_cntl); } - //pclog("VGA on = %d.\n", vga_on); + 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; @@ -182,19 +213,24 @@ xga_recalctimings(svga_t *svga) xga->ma_latch = xga->disp_start_addr; + 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) { - svga->clock = (cpuclock * (double) (1ull << 32)) / 41539000.0; - } else { - svga->clock = (cpuclock * (double) (1ull << 32)) / 25175000.0; - } + 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 + svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; break; case 1: - svga->clock = (cpuclock * (double) (1ull << 32)) / 28322000.0; + xga_log("HDISP VGA1 = %d, XGA = %d.\n", svga->hdisp, xga->h_disp); + svga->clock = (cpuclock * (double) (1ULL << 32)) / 28322000.0; break; case 3: - svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; + svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + break; + + default: break; } } @@ -334,22 +370,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; @@ -365,7 +408,7 @@ 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) || ((xga->disp_cntl_2 & 7) > 3)) + 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) { if (xga->linear_endian_reverse && !(xga->access_mode & 8)) @@ -383,7 +426,9 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) 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); + + 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: @@ -417,10 +462,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; @@ -444,9 +492,13 @@ 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; } } @@ -454,9 +506,10 @@ static void xga_ext_outb(uint16_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + 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; @@ -466,20 +519,28 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) 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: @@ -496,6 +557,9 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) xga->regs[xga->regs_idx] = val; xga_ext_out_reg(xga, svga, xga->regs_idx, xga->regs[xga->regs_idx]); break; + + default: + break; } } @@ -503,8 +567,8 @@ static uint8_t xga_ext_inb(uint16_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; - uint8_t ret = 0xff; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0; uint8_t index; switch (addr & 0x0f) { @@ -646,6 +710,9 @@ xga_ext_inb(uint16_t addr, void *priv) case 0x54: ret = xga->clk_sel_1; break; + case 0x55: + ret = xga->border_color; + break; case 0x59: ret = xga->direct_color; @@ -685,6 +752,9 @@ xga_ext_inb(uint16_t addr, void *priv) svga->dac_addr = (svga->dac_addr + 1) & 0xff; ret = svga->vgapal[index].b; break; + + default: + break; } break; @@ -703,7 +773,8 @@ xga_ext_inb(uint16_t addr, void *priv) 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; @@ -727,9 +798,13 @@ xga_ext_inb(uint16_t addr, void *priv) 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", CS, cpu_state.pc, addr, ret); + return ret; } @@ -743,37 +818,17 @@ xga_ext_inb(uint16_t addr, void *priv) #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 READL(addr, dat) \ - dat = *(uint32_t *) &xga->vram[(addr) & (xga->vram_mask)]; - -#define READL_REVERSE(addr, dat) \ - dat = xga->vram[(addr + 3) & (xga->vram_mask - 3)] & 0xff; \ - dat |= (xga->vram[(addr + 2) & (xga->vram_mask - 3)] << 8); \ - dat |= (xga->vram[(addr + 1) & (xga->vram_mask - 3)] << 16); \ - dat |= (xga->vram[(addr) & (xga->vram_mask - 3)] << 24); +#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 WRITEL(addr, dat) \ - *(uint32_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; \ - xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; - -#define WRITEL_REVERSE(addr, dat) \ - xga->vram[((addr + 3)) & (xga->vram_mask - 3)] = dat & 0xff; \ - xga->vram[((addr + 2)) & (xga->vram_mask - 3)] = dat >> 8; \ - xga->vram[((addr + 1)) & (xga->vram_mask - 3)] = dat >> 16; \ - xga->vram[((addr)) & (xga->vram_mask - 3)] = dat >> 24; \ +#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) \ @@ -834,7 +889,7 @@ xga_ext_inb(uint16_t addr, void *priv) 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); \ @@ -851,12 +906,12 @@ xga_ext_inb(uint16_t addr, void *priv) 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))) @@ -870,25 +925,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; @@ -909,19 +971,28 @@ 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; @@ -934,46 +1005,30 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int 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); - } - return byte; - case 5: /*24-bit*/ - addr += (y * (width << 2)); - addr += (x << 2); - if (!skip) { - if ((xga->accel.px_map_format[map] & 8)) { - if (xga->linear_endian_reverse) { - READL(addr, byte); - } else { - READL_REVERSE(addr, byte); - } - } else { - READL(addr, byte); - } + 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 { - byte = mem_readl_phys(addr); + 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; @@ -989,20 +1044,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) { @@ -1018,6 +1074,28 @@ 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; @@ -1029,34 +1107,20 @@ 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; - case 5: /*24-bit*/ - addr += (y * (width) << 2); - addr += (x << 2); - if (!skip) { - if ((xga->accel.px_map_format[map] & 8)) { - if (xga->linear_endian_reverse) { - WRITEL(addr, pixel); - } else { - WRITEL_REVERSE(addr, pixel); - } - } else { - WRITEL(addr, pixel); - } - } - mem_writel_phys(addr, pixel); + + default: break; } } @@ -1064,7 +1128,7 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui 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; @@ -1074,17 +1138,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) { @@ -1120,14 +1184,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; @@ -1146,8 +1213,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; @@ -1190,7 +1257,7 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) 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; @@ -1204,48 +1271,40 @@ xga_line_draw_write(svga_t *svga) int err; int tmpswap; int steep = 1; - int xdir; - int ydir; + int xdir = (xga->accel.octant & 0x04) ? -1 : 1; + int ydir = (xga->accel.octant & 0x02) ? -1 : 1; int y = xga->accel.blt_width; int x = 0; - int dx; - int dy; + int16_t dx; + int16_t dy; + int draw_pixel; - dminor = ((int16_t) xga->accel.bres_k1); + dminor = xga->accel.bres_k1; if (xga->accel.bres_k1 & 0x2000) dminor |= ~0x1fff; dminor >>= 1; - destxtmp = ((int16_t) xga->accel.bres_k2); + destxtmp = xga->accel.bres_k2; if (xga->accel.bres_k2 & 0x2000) destxtmp |= ~0x1fff; dmajor = -(destxtmp - (dminor << 1)) >> 1; - err = ((int16_t) xga->accel.bres_err_term); + err = 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; - } + err |= ~0x1fff; 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.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.octant & 0x01) { steep = 0; SWAP(dx, dy); @@ -1254,11 +1313,12 @@ xga_line_draw_write(svga_t *svga) if (xga->accel.pat_src == 8) { while (y >= 0) { + draw_pixel = 1; if (xga->accel.command & 0xc0) { if (steep) { 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; @@ -1270,12 +1330,27 @@ xga_line_draw_write(svga_t *svga) 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); + else if ((xga->accel.command & 0x30) == 0x30) { + if (err < 0) + draw_pixel = 0; + else { + if (ydir == -1) { /*Bottom-to-Top*/ + if (!x) + draw_pixel = 0; + } else { /*Top-to-Bottom*/ + if (!y) + draw_pixel = 0; + } + } + if (draw_pixel) + 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 ((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); + 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, dy, dx, 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; @@ -1287,13 +1362,24 @@ xga_line_draw_write(svga_t *svga) 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); + else if ((xga->accel.command & 0x30) == 0x30) { + if (xdir == -1) { /*Bottom-to-Top*/ + if (!x) + draw_pixel = 0; + } else { /*Top-to-Bottom*/ + if (!y) + draw_pixel = 0; + } + if (draw_pixel) + 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 (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); + 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; @@ -1305,10 +1391,25 @@ xga_line_draw_write(svga_t *svga) 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); + else if ((xga->accel.command & 0x30) == 0x30) { + if (err < 0) + draw_pixel = 0; + else { + if (ydir == -1) { /*Bottom-to-Top*/ + if (!x) + draw_pixel = 0; + } else { /*Top-to-Bottom*/ + if (!y) + draw_pixel = 0; + } + } + if (draw_pixel) + 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); + 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, dy, dx, 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; @@ -1320,6 +1421,17 @@ xga_line_draw_write(svga_t *svga) 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); + else if ((xga->accel.command & 0x30) == 0x30) { + if (xdir == -1) { /*Bottom-to-Top*/ + if (!x) + draw_pixel = 0; + } else { /*Top-to-Bottom*/ + if (!y) + draw_pixel = 0; + } + if (draw_pixel) + 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); + } } } } @@ -1328,7 +1440,7 @@ xga_line_draw_write(svga_t *svga) break; } - while (err > 0) { + while (err >= 0) { dy += ydir; err -= (dmajor << 1); } @@ -1350,17 +1462,13 @@ xga_line_draw_write(svga_t *svga) } } -static int16_t -xga_dst_wrap(int16_t addr) -{ - addr &= 0x1fff; - return (addr & 0x1800) == 0x1800 ? (addr | 0xf800) : addr; -} +#undef SWAP static void xga_bitblt(svga_t *svga) { - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; + uint8_t area_state = 0; uint32_t src_dat; uint32_t dest_dat; uint32_t old_dest_dat; @@ -1374,21 +1482,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; @@ -1397,48 +1498,71 @@ 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_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); + } } } @@ -1446,15 +1570,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 @@ -1463,8 +1591,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; } } @@ -1475,13 +1603,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; @@ -1493,69 +1620,162 @@ 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); + 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 & 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; + if (((xga->accel.command >> 24) & 0x0f) == 0x0a) { + 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) + area_state ^= 1; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, 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))) { + if (area_state) + 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; - 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.px_map_format[xga->accel.dst_map] & 7) <= 3) + src_dat &= 0xff; + + 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(area_state, 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)) { + if (area_state) + 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; + + if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) <= 3) + src_dat &= 0xff; + + 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(area_state, 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 + 1) & srcwidth) | (xga->accel.sx & ~srcwidth); + xga->accel.px = ((xga->accel.px + 1) & patwidth) | (xga->accel.px & ~patwidth); + dx++; + xga->accel.x--; + if (xga->accel.x < 0) { + area_state = 0; + xga->accel.y--; + xga->accel.x = xga->accel.blt_width & 0xfff; - 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.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 += ydir; + dy += ydir; + + if (xga->accel.y < 0) { + xga->accel.dst_map_x = dx; + xga->accel.dst_map_y = dy; + 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; + } + 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.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; - - 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; + } } } } @@ -1685,7 +1905,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); @@ -1952,39 +2175,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 3: /*Bresenham Line Draw Read*/ - // pclog("Line Draw Read\n"); + case 2: /*Short Stroke Vectors Read */ + xga_log("Short Stroke Vectors Read.\n"); break; - case 4: /*Short Stroke Vectors*/ + case 3: /*Bresenham Line Draw Read*/ + xga_log("Line Draw Read\n"); + break; + 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) { @@ -2009,6 +2257,9 @@ exec_command: goto exec_command; } break; + + default: + break; } } } @@ -2017,40 +2268,43 @@ static void xga_memio_writeb(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + 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 *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + 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 *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + 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) { - if (!xga_has_vga) + if (xga_standalone_enabled) temp = xga->bios_rom.rom[addr]; else temp = xga->vga_bios_rom.rom[addr]; @@ -2118,6 +2372,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; } } @@ -2128,12 +2385,13 @@ static uint8_t xga_memio_readb(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + 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; } @@ -2141,13 +2399,14 @@ static uint16_t xga_memio_readw(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + 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; } @@ -2155,7 +2414,7 @@ static uint32_t xga_memio_readl(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint32_t temp; temp = xga_mem_read(addr, xga, svga); @@ -2163,14 +2422,15 @@ xga_memio_readl(uint32_t addr, void *priv) 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("Read MEMIOL = %04x, temp = %08x\n", 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; @@ -2208,6 +2468,9 @@ xga_hwcursor_draw(svga_t *svga, int displine) /* Complement */ p[x_pos] ^= 0xffffff; break; + + default: + break; } } @@ -2251,8 +2514,50 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga) } static void -xga_render_8bpp(xga_t *xga, svga_t *svga) +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 >> 4) & 0x0f]; + p[1] = xga->pallook[dat & 0x0f]; + p[2] = xga->pallook[(dat >> 12) & 0x0f]; + p[3] = xga->pallook[(dat >> 8) & 0x0f]; + p[4] = xga->pallook[(dat >> 20) & 0x0f]; + p[5] = xga->pallook[(dat >> 16) & 0x0f]; + p[6] = xga->pallook[(dat >> 28) & 0x0f]; + p[7] = xga->pallook[(dat >> 24) & 0x0f]; + + dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]); + p[9] = xga->pallook[dat & 0x0f]; + p[11] = xga->pallook[(dat >> 8) & 0x0f]; + p[13] = xga->pallook[(dat >> 16) & 0x0f]; + p[15] = xga->pallook[(dat >> 24) & 0x0f]; + + xga->ma += 8; + p += 16; + } + xga->ma &= xga->vram_mask; + } +} + +static void +xga_render_8bpp(svga_t *svga) +{ + xga_t *xga = (xga_t *) svga->xga; uint32_t *p; uint32_t dat; @@ -2268,16 +2573,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; @@ -2287,8 +2592,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; @@ -2329,7 +2635,7 @@ static void xga_write(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; if (!xga->on) { svga_write(addr, val, svga); @@ -2342,42 +2648,122 @@ xga_write(uint32_t addr, uint8_t val, void *priv) 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 *priv) -{ - // pclog("[%04X:%08X]: WriteB\n", CS, cpu_state.pc); - xga_write(addr, val, priv); -} - static void xga_writew(uint32_t addr, uint16_t val, void *priv) { - // pclog("[%04X:%08X]: WriteW\n", CS, cpu_state.pc); - xga_write(addr, val, priv); - xga_write(addr + 1, val >> 8, priv); + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + + 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 *priv) { - // pclog("[%04X:%08X]: WriteL\n", CS, cpu_state.pc); - xga_write(addr, val, priv); - xga_write(addr + 1, val >> 8, priv); - xga_write(addr + 2, val >> 16, priv); - xga_write(addr + 3, val >> 24, priv); + 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 uint8_t +xga_read(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0xff; + + if (!xga->on) { + ret = svga_read(addr, svga); + return ret; + } + + addr &= xga->banked_mask; + addr += xga->read_bank; + + if (addr >= xga->vram_size) + return ret; + + cycles -= svga->monitor->mon_video_timing_read_b; + + if (xga->access_mode & 8) { + if ((xga->access_mode & 7) == 4) + addr ^= 1; + } + + ret = xga->vram[addr & xga->vram_mask]; + + return ret; +} + +static uint16_t +xga_readw(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint16_t ret = 0xffff; + + if (!xga->on) { + ret = svga_readw(addr, svga); + return ret; + } + + ret = xga_read(addr, svga); + ret |= (xga_read(addr + 1, svga) << 8); + + return ret; +} + +static uint32_t +xga_readl(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint32_t ret = 0xffffffff; + + if (!xga->on) { + ret = svga_readl(addr, svga); + return ret; + } + + 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 void xga_write_linear(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; if (!xga->on) { svga_write_linear(addr, val, svga); @@ -2389,7 +2775,17 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv) if (addr >= xga->vram_size) return; - cycles -= video_timing_write_b; + cycles -= svga->monitor->mon_video_timing_write_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; + } + } xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; xga->vram[addr & xga->vram_mask] = val; @@ -2398,44 +2794,23 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv) static void xga_writew_linear(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + const xga_t *xga = (xga_t *) svga->xga; if (!xga->on) { svga_writew_linear(addr, val, svga); return; } - if (xga->linear_endian_reverse) { - if (xga->accel.px_map_format[xga->accel.dst_map] == 0x0c) { - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - } else if (xga->accel.px_map_format[xga->accel.dst_map] == 4) { - xga_write_linear(addr + 1, val, priv); - xga_write_linear(addr, val >> 8, priv); - } else { - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - } - } else { - if (xga->accel.px_map_format[xga->accel.dst_map] == 0x0c) { - xga_write_linear(addr + 1, val, priv); - xga_write_linear(addr, val >> 8, priv); - } else if (xga->accel.px_map_format[xga->accel.dst_map] == 4) { - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - } else { - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - } - } + xga_write_linear(addr, val, priv); + xga_write_linear(addr + 1, val >> 8, priv); } static void xga_writel_linear(uint32_t addr, uint32_t val, void *priv) { - svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + const xga_t *xga = (xga_t *) svga->xga; if (!xga->on) { svga_writel_linear(addr, val, svga); @@ -2448,65 +2823,12 @@ xga_writel_linear(uint32_t addr, uint32_t val, void *priv) xga_write_linear(addr + 3, val >> 24, priv); } -static uint8_t -xga_read(uint32_t addr, void *priv) -{ - svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; - - if (!xga->on) - return svga_read(addr, svga); - - addr &= xga->banked_mask; - addr += xga->read_bank; - - if (addr >= xga->vram_size) - return 0xff; - - cycles -= video_timing_read_b; - - return xga->vram[addr & xga->vram_mask]; -} - -static uint8_t -xga_readb(uint32_t addr, void *priv) -{ - uint8_t ret; - - ret = xga_read(addr, priv); - - return ret; -} - -static uint16_t -xga_readw(uint32_t addr, void *priv) -{ - uint16_t ret; - - ret = xga_read(addr, priv); - ret |= (xga_read(addr + 1, priv) << 8); - - return ret; -} - -static uint32_t -xga_readl(uint32_t addr, void *priv) -{ - uint32_t ret; - - ret = xga_read(addr, priv); - ret |= (xga_read(addr + 1, priv) << 8); - ret |= (xga_read(addr + 2, priv) << 16); - ret |= (xga_read(addr + 3, priv) << 24); - - return ret; -} - static uint8_t xga_read_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) priv; - 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); @@ -2514,9 +2836,19 @@ xga_read_linear(uint32_t addr, void *priv) 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]; } @@ -2524,54 +2856,54 @@ xga_read_linear(uint32_t addr, void *priv) static uint16_t xga_readw_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) priv; - 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, priv) | (xga_read_linear(addr + 1, priv) << 8); - } else if (xga->accel.px_map_format[xga->accel.src_map] == 4) { - ret = xga_read_linear(addr + 1, priv) | (xga_read_linear(addr, priv) << 8); - } else - ret = xga_read_linear(addr, priv) | (xga_read_linear(addr + 1, priv) << 8); - } else { - if (xga->accel.px_map_format[xga->accel.src_map] == 0x0c) { - ret = xga_read_linear(addr + 1, priv) | (xga_read_linear(addr, priv) << 8); - } else if (xga->accel.px_map_format[xga->accel.src_map] == 4) { - ret = xga_read_linear(addr, priv) | (xga_read_linear(addr + 1, priv) << 8); - } else - ret = xga_read_linear(addr, priv) | (xga_read_linear(addr + 1, priv) << 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 *priv) { - svga_t *svga = (svga_t *) priv; - 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, priv) | (xga_read_linear(addr + 1, priv) << 8) | (xga_read_linear(addr + 2, priv) << 16) | (xga_read_linear(addr + 3, priv) << 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; } @@ -2589,8 +2921,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; @@ -2616,7 +2949,7 @@ 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) { @@ -2643,15 +2976,9 @@ 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); - } + xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7)); + if (xga->interlace) + xga->maback += (xga->rowoffset << (xga->disp_cntl_2 & 7)); xga->maback &= xga->vram_mask; xga->ma = xga->maback; } else { @@ -2733,14 +3060,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; } @@ -2748,7 +3077,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) @@ -2757,8 +3086,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; @@ -2780,14 +3109,17 @@ 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; } @@ -2796,10 +3128,12 @@ static void xga_mca_reset(void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + 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); } @@ -2807,12 +3141,12 @@ static void xga_reset(void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + 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; } @@ -2821,10 +3155,10 @@ static uint8_t xga_pos_in(uint16_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; - uint8_t ret = 0xff; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0xff; - if (xga_has_vga) { + if (!xga_standalone_enabled) { switch (addr) { case 0x0100: case 0x0101: @@ -2844,11 +3178,12 @@ xga_pos_in(uint16_t addr, void *priv) ret = xga->pos_idx & 0xff; break; case 0x0103: - if (!(xga->pos_idx & 3)) { + if (!(xga->pos_idx & 3)) ret = xga->pos_regs[3]; - } else + else ret = 0; - //pclog("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); + + xga_log("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); break; case 0x0104: switch (xga->pos_idx & 3) { @@ -2864,8 +3199,12 @@ xga_pos_in(uint16_t addr, void *priv) case 3: ret = 0; break; + + default: + break; } - //pclog("POS IDX for 0104 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); + + xga_log("POS IDX for 0104 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); break; case 0x0108: case 0x0109: @@ -2883,6 +3222,9 @@ xga_pos_in(uint16_t addr, void *priv) ret |= xga->isa_pos_enable; break; + + default: + break; } } else { switch (addr) { @@ -2917,6 +3259,9 @@ xga_pos_in(uint16_t addr, void *priv) ret |= xga->isa_pos_enable; break; + + default: + break; } } return ret; @@ -2926,16 +3271,16 @@ static void xga_pos_out(uint16_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; - if (xga_has_vga) { + 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); - //pclog("POS IDX Write = %04x.\n", xga->pos_idx); + xga->pos_idx = (xga->pos_idx & 0xff00) | val; + xga_log("POS IDX Write = %04x.\n", xga->pos_idx); break; case 0x0108: case 0x0109: @@ -2945,9 +3290,12 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) case 0x010d: case 0x010e: case 0x010f: - xga->instance_num = addr & 7; + xga->instance_num = addr & 7; xga->isa_pos_enable = val & 0x08; break; + + default: + break; } } else { switch (addr) { @@ -2959,31 +3307,34 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) case 0x010d: case 0x010e: case 0x010f: - xga->instance_num = addr & 7; + xga->instance_num = addr & 7; xga->isa_pos_enable = val & 0x08; break; + + default: + break; } } } -static void - * - xga_init(const device_t *info) +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; + + 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->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; @@ -2996,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); } @@ -3021,29 +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 { - if (xga_has_vga) { + if (!xga_standalone_enabled) rom_init(&xga->vga_bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - } else + 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); + 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_has_vga ? xga->vga_bios_rom.rom : 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); @@ -3054,22 +3402,20 @@ 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_has_vga) + 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); + 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) +static void * +svga_xga_init(const device_t *info) { - svga_t *svga = malloc(sizeof(svga_t)); - memset(svga, 0, sizeof(svga_t)); + svga_t *svga = (svga_t *) calloc(1, sizeof(svga_t)); video_inform(VIDEO_FLAG_TYPE_XGA, &timing_xga_isa); @@ -3083,8 +3429,7 @@ static void svga->bpp = 8; svga->miscout = 1; - xga_has_vga = 1; - xga_enabled = 1; + xga_active = 1; return xga_init(info); } @@ -3093,11 +3438,13 @@ static void xga_close(void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; + xga_t *xga = (xga_t *) svga->xga; if (svga) { free(xga->vram); free(xga->changedvram); + + free(xga); } } @@ -3152,7 +3499,7 @@ static const device_config_t xga_mca_configuration[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; static const device_config_t xga_isa_configuration[] = { @@ -3237,7 +3584,7 @@ static const device_config_t xga_isa_configuration[] = { }, }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t xga_device = { @@ -3285,7 +3632,7 @@ const device_t inmos_isa_device = { void xga_device_add(void) { - if (!xga_enabled || (xga_has_vga && 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 7ecb0e5f9..710449746 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 @@ -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 30caff9e2..7b4b1f7b0 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,26 +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; -#if 0 - pclog("dx=%d, dy=%d, dwheel=%d\n", mouse_x, mouse_y, mouse_z); -#endif - } + 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; @@ -110,25 +106,6 @@ 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); } @@ -165,9 +142,8 @@ 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"); diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 806f2b45b..0cf34d6c6 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -64,9 +64,6 @@ ifeq ($(DEV_BUILD), y) ifndef LASERXT LASERXT := y endif - ifndef MGA - MGA := y - endif ifndef OLIVETTI OLIVETTI := y endif @@ -128,9 +125,6 @@ else ifndef LASERXT LASERXT := n endif - ifndef MGA - MGA := n - endif ifndef OLIVETTI OLIVETTI := n endif @@ -269,8 +263,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 +298,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,11 +490,6 @@ 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 @@ -531,7 +541,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,23 +553,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 row.o smram.o spd.o sst_flash.o - -CPU808XOBJ := queue.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 \ - x86_ops_mmx.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 \ @@ -565,7 +577,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 \ @@ -605,12 +617,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 \ @@ -635,6 +649,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 @@ -663,7 +678,11 @@ NETOBJ := network.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 @@ -679,6 +698,8 @@ SNDOBJ := sound.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ midi.o \ + midi_opl4.o \ + midi_opl4_yrw801.o \ snd_speaker.o \ snd_pssj.o \ snd_ps1.o \ @@ -714,6 +735,7 @@ VIDOBJ := agpgart.o video.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_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ @@ -735,6 +757,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 @@ -775,7 +798,7 @@ ifeq ($(RTMIDI), y) SNDOBJ += midi_rtmidi.o endif -OBJ := $(MAINOBJ) $(CPU808XOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ +OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ $(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \ $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \ $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ) @@ -811,13 +834,21 @@ else 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 ae7e3daf8..6c0982c5c 100644 --- a/src/win/languages/cs-CZ.rc +++ b/src/win/languages/cs-CZ.rc @@ -480,7 +480,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 diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc index 5e6f38221..031f935cd 100644 --- a/src/win/languages/de-DE.rc +++ b/src/win/languages/de-DE.rc @@ -480,7 +480,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 diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index 9f6f178a6..01e18f71a 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -480,7 +480,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 diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index b1163f8f3..6ca6945d6 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -480,7 +480,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 diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc index 49fea1fae..1fd0bceff 100644 --- a/src/win/languages/es-ES.rc +++ b/src/win/languages/es-ES.rc @@ -480,7 +480,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 diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc index 1c5cda78b..3f875cb3d 100644 --- a/src/win/languages/fi-FI.rc +++ b/src/win/languages/fi-FI.rc @@ -480,7 +480,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 diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index 1d4643eeb..1ad5a4da1 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -480,7 +480,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 diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc index 5225ff969..9497a7b0d 100644 --- a/src/win/languages/hr-HR.rc +++ b/src/win/languages/hr-HR.rc @@ -480,7 +480,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 diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index aa7e06eff..ab91d43f5 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -484,7 +484,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 diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc index f546fc1d4..cb6e7afa1 100644 --- a/src/win/languages/it-IT.rc +++ b/src/win/languages/it-IT.rc @@ -481,7 +481,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 diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index fb5106134..bf9509453 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,47 +241,47 @@ 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_XGA "XGAグラフィック" @@ -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_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 "HDコントローラー:" -#define STR_FDC "FDコントローラー:" -#define STR_IDE_TER "第三のIDEコントローラー" -#define STR_IDE_QUA "第四のIDEコントローラー" +#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,34 +402,34 @@ 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 @@ -441,31 +441,31 @@ 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_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_2112 "SDLが初期化できません。SDL2.dllが必要です" - IDS_2113 "使用中のマシンをハードリセットしますか?" + IDS_2113 "使用中のマシンをハードリ セットしますか?" IDS_2114 "86Boxを終了しますか?" IDS_2115 "Ghostscriptが初期化できません" IDS_2116 "光磁気 %i (%ls): %ls" @@ -475,12 +475,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 @@ -489,90 +489,90 @@ BEGIN #define LIB_NAME_PCAP "libpcap" #endif IDS_2130 LIB_NAME_PCAP "がインストールされてるか、" LIB_NAME_PCAP "に対応したネットワークに接続されてるか確認してください。" - IDS_2131 "不正な設定です" + 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)ファイルとして保存されます。" - 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" @@ -624,10 +624,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 4fd952c38..360d6e36b 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -480,7 +480,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 diff --git a/src/win/languages/pl-PL.rc b/src/win/languages/pl-PL.rc index 442a225ed..f835ad9eb 100644 --- a/src/win/languages/pl-PL.rc +++ b/src/win/languages/pl-PL.rc @@ -480,7 +480,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 diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index db85ed021..00e9c243d 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -483,7 +483,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 diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc index 00f5af336..88db4f18c 100644 --- a/src/win/languages/pt-PT.rc +++ b/src/win/languages/pt-PT.rc @@ -480,7 +480,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 diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index 458b0e874..647b43d44 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -480,7 +480,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 diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc index f9d2fb82a..b3a00c9de 100644 --- a/src/win/languages/sl-SI.rc +++ b/src/win/languages/sl-SI.rc @@ -480,7 +480,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 diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc index cb45eab74..78e7b4b87 100644 --- a/src/win/languages/tr-TR.rc +++ b/src/win/languages/tr-TR.rc @@ -480,7 +480,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 diff --git a/src/win/languages/uk-UA.rc b/src/win/languages/uk-UA.rc index e282e467b..41bf85f1a 100644 --- a/src/win/languages/uk-UA.rc +++ b/src/win/languages/uk-UA.rc @@ -480,7 +480,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 diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index 3320af15f..92afaf86d 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 或鼠标中键释放鼠标" @@ -440,7 +440,7 @@ BEGIN IDS_2084 "H" IDS_2085 "S" IDS_2086 "MB" - IDS_2087 "Speed" + IDS_2087 "速度" IDS_2088 "检查 BPB" IDS_2089 "KB" IDS_2090 "无法初始化视频渲染器。" @@ -463,13 +463,13 @@ 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_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_2112 "无法初始化 SDL,需要 SDL2.dll" 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 "退出" @@ -480,7 +480,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 @@ -497,12 +497,12 @@ BEGIN #endif IDS_2133 LIB_NAME_GS " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" 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" @@ -511,9 +511,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 "恢复执行" @@ -523,13 +523,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 @@ -542,27 +542,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)" @@ -570,7 +570,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 0aea4a635..039993e5d 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 "設定" @@ -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 "映像格式:" @@ -480,7 +480,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 diff --git a/src/win/win.c b/src/win/win.c index f166d559d..21ff6646c 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -65,30 +65,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 +303,7 @@ plat_get_string(int i) else str = lpRCstr7168[i - 7168].str; - return ((wchar_t *) str); + return str; } #ifdef MTR_ENABLED @@ -382,7 +383,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 +402,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 +426,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 +443,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 +451,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 +490,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) free(argbuf); free(argv); - return (1); + return 1; } extern int gfxcard[2]; @@ -506,14 +510,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; @@ -648,14 +654,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 +681,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 +733,7 @@ plat_remove(char *path) } void -path_normalize(char *path) +path_normalize(UNUSED(char *path)) { /* No-op */ } @@ -734,9 +742,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 +763,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 +787,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 +817,7 @@ path_get_filename(char *s) c--; } - return (s); + return s; } char * @@ -807,7 +826,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 +873,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 +949,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 +967,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 +1012,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 +1057,7 @@ plat_vidapi_name(int api) break; } - return (name); + return name; } int @@ -1062,13 +1081,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 +1129,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 +1249,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 +1270,12 @@ 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 take_screenshot(void) { @@ -1280,3 +1306,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 27e4e0a49..37b741c29 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); diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index 0f233cb3a..92ab6b614 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 b58ef88d0..15b00bf3f 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 5658b14d5..df8a99a05 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -318,7 +318,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 6f2a1e4c0..c5c2a3d6e 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. @@ -99,8 +98,6 @@ 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) return; @@ -140,14 +137,11 @@ 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 @@ -373,10 +367,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); @@ -406,9 +400,9 @@ win_joystick_handle(PRAWINPUT raw) /* 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 +415,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 +449,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 a1c380668..f313522a9 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 0e4f581dd..66ad60c73 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -150,7 +150,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; @@ -247,7 +247,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 72f8561f0..54be91e6c 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 93d7396ae..549a495b9 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 3e31f12de..f2b185eaa 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 266660826..d0a245a45 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 1f866d273..094b3d063 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 47cc755dc..9689f3ab2 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 d095dcd31..ee93321a8 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 cae5f8147..ea9c8455d 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 cfe920aa7..b2d09b1d0 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 9ded351b9..139c387a8 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,12 +726,11 @@ win_settings_machine_recalc_fpu(HWND hdlg) c++; } - 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)); - 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 @@ -737,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) @@ -756,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)); @@ -802,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)); @@ -910,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; @@ -945,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; @@ -1002,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; @@ -1046,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)]; @@ -1098,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); @@ -1124,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; @@ -1347,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: @@ -1408,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; @@ -1441,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; } @@ -1463,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; @@ -1799,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: @@ -1813,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; @@ -1877,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; @@ -2102,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; @@ -2448,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); } } @@ -2463,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; @@ -2820,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 @@ -2876,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); @@ -3029,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; @@ -3198,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; @@ -3282,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(); } @@ -3301,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); } @@ -3330,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); @@ -3386,8 +3398,8 @@ hdd_add_file_open_error: 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) @@ -3432,7 +3444,7 @@ hdd_add_file_open_error: no_update = 0; } - fclose(f); + fclose(fp); } h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); @@ -3623,8 +3635,8 @@ hdd_add_file_open_error: 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: @@ -3968,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; @@ -4028,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; @@ -4063,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; @@ -4071,7 +4083,7 @@ win_settings_cdrom_drives_recalc_list(HWND hdlg) if (ListView_SetItem(hwndList, &lvI) == -1) return FALSE; -*/ +#endif } return TRUE; @@ -4094,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; @@ -4156,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; @@ -4384,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 }; @@ -4450,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; @@ -4508,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; @@ -4541,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; @@ -4549,7 +4561,7 @@ win_settings_cdrom_drives_update_item(HWND hdlg, int i) if (ListView_SetItem(hwndList, &lvI) == -1) return; -*/ +#endif } static void @@ -4571,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; @@ -4629,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; @@ -4700,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) { @@ -4723,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; @@ -4801,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; @@ -4863,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; @@ -4910,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)); } @@ -4919,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)); } @@ -4971,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: @@ -5012,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: @@ -5095,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; @@ -5143,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: @@ -5167,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: @@ -5198,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: @@ -5221,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: @@ -5351,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; diff --git a/src/win/win_snd_gain.c b/src/win/win_snd_gain.c index 641a83a5c..5297661bf 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 48e7801a5..5bedb846d 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 73f2d7231..2cf8d84f4 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_ui.c b/src/win/win_ui.c index deb2eb6ec..73119140c 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -57,25 +57,27 @@ #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; int dpi = 96; +int status_icons_fullscreen = 0; /* unused. */ + extern char openfilestring[512]; extern WCHAR wopenfilestring[512]; @@ -396,10 +398,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 +428,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 +482,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 +505,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 +882,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 +920,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 +976,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 +994,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 +1143,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; } - return (0); + return 0; } static LRESULT CALLBACK @@ -1182,7 +1188,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 +1248,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 +1257,7 @@ ui_init(int nCmdShow) set_language(helper_lang); win_settings_open(NULL); - return (0); + return 0; } #ifdef DISCORD @@ -1286,19 +1292,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 +1384,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 +1398,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 +1407,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 +1426,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. */ @@ -1640,13 +1646,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 f9cf6783c..5fdfc175b 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "4.0", + "version-string": "4.1", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later", @@ -9,7 +9,8 @@ "libpng", "sdl2", "rtmidi", - "libslirp" + "libslirp", + "fluidsynth" ], "features": { "qt-ui": {